Skip to content

Instantly share code, notes, and snippets.

@angelsl
Last active December 14, 2015 10:10
Show Gist options
  • Save angelsl/5070272 to your computer and use it in GitHub Desktop.
Save angelsl/5070272 to your computer and use it in GitHub Desktop.
smdk4210 kernel diff
This file has been truncated, but you can view the full file.
git diff 52f91d88 --diff-filter=M -p --stat=120 --src-prefix=aosp-v3.0/ --dst-prefix=smdk4210/ !(Documentation) > ~/aosp-smdk4210jb.diff
https://android.googlesource.com/kernel/common/+/52f91d88
Makefile | 15 +-
arch/Kconfig | 3 +
arch/alpha/include/asm/futex.h | 2 +-
arch/arm/Kconfig | 78 +-
arch/arm/Kconfig.debug | 5 +
arch/arm/Makefile | 3 +-
arch/arm/boot/Makefile | 4 +
arch/arm/boot/compressed/Makefile | 5 +
arch/arm/boot/compressed/head.S | 40 +-
arch/arm/common/gic.c | 68 +-
arch/arm/common/pl330.c | 123 +-
arch/arm/include/asm/assembler.h | 9 +
arch/arm/include/asm/bitops.h | 4 +-
arch/arm/include/asm/cacheflush.h | 40 +
arch/arm/include/asm/device.h | 3 +
arch/arm/include/asm/dma-mapping.h | 18 +
arch/arm/include/asm/hardware/gic.h | 5 +-
arch/arm/include/asm/hardware/pl330.h | 1 +
arch/arm/include/asm/hwcap.h | 36 +-
arch/arm/include/asm/mach/map.h | 4 +
arch/arm/include/asm/memory.h | 1 +
arch/arm/include/asm/outercache.h | 8 +
arch/arm/include/asm/perf_event.h | 2 +
arch/arm/include/asm/sections.h | 8 +
arch/arm/include/asm/setup.h | 2 +
arch/arm/include/asm/tlb.h | 10 +-
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/perf_event.c | 6 +
arch/arm/kernel/perf_event_v7.c | 344 +-
arch/arm/kernel/setup.c | 17 +
arch/arm/kernel/smp.c | 65 +-
arch/arm/kernel/smp_scu.c | 16 +-
arch/arm/kernel/stacktrace.c | 15 +-
arch/arm/lib/copy_from_user.S | 9 +
arch/arm/lib/copy_template.S | 46 +-
arch/arm/lib/copy_to_user.S | 9 +
arch/arm/lib/memcpy.S | 9 +
arch/arm/mach-s3c2410/include/mach/dma.h | 4 +
arch/arm/mach-s3c2410/include/mach/pm-core.h | 3 +
arch/arm/mach-s3c64xx/Kconfig | 1 +
arch/arm/mach-s3c64xx/cpu.c | 22 +-
arch/arm/mach-s3c64xx/dev-onenand1.c | 10 +-
arch/arm/mach-s3c64xx/include/mach/dma.h | 5 +
arch/arm/mach-s3c64xx/include/mach/pm-core.h | 19 +-
arch/arm/mach-s3c64xx/irq.c | 12 +-
arch/arm/mach-s3c64xx/mach-anw6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-hmt.c | 2 +-
arch/arm/mach-s3c64xx/mach-mini6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-ncp.c | 2 +-
arch/arm/mach-s3c64xx/mach-real6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-smartq5.c | 2 +-
arch/arm/mach-s3c64xx/mach-smartq7.c | 2 +-
arch/arm/mach-s3c64xx/mach-smdk6410.c | 43 +-
arch/arm/mach-s3c64xx/setup-fb-24bpp.c | 1 -
arch/arm/mach-s5p64x0/Kconfig | 2 +
arch/arm/mach-s5p64x0/mach-smdk6440.c | 54 +-
arch/arm/mach-s5p64x0/mach-smdk6450.c | 54 +-
arch/arm/mach-s5pc100/Kconfig | 1 +
arch/arm/mach-s5pc100/clock.c | 37 +-
arch/arm/mach-s5pc100/mach-smdkc100.c | 57 +-
arch/arm/mach-s5pc100/setup-fb-24bpp.c | 1 -
arch/arm/mach-s5pv210/Kconfig | 22 +
arch/arm/mach-s5pv210/Makefile | 4 +-
arch/arm/mach-s5pv210/Makefile.boot | 3 +
arch/arm/mach-s5pv210/clock.c | 148 +-
arch/arm/mach-s5pv210/cpu.c | 14 +-
arch/arm/mach-s5pv210/cpufreq.c | 218 +-
arch/arm/mach-s5pv210/dev-audio.c | 7 +-
arch/arm/mach-s5pv210/dma.c | 74 +-
arch/arm/mach-s5pv210/include/mach/irqs.h | 4 +-
arch/arm/mach-s5pv210/include/mach/map.h | 14 +-
arch/arm/mach-s5pv210/include/mach/memory.h | 4 +
arch/arm/mach-s5pv210/include/mach/pm-core.h | 3 +
arch/arm/mach-s5pv210/include/mach/regs-clock.h | 31 +
arch/arm/mach-s5pv210/mach-aquila.c | 2 +-
arch/arm/mach-s5pv210/mach-goni.c | 2 +-
arch/arm/mach-s5pv210/mach-smdkc110.c | 589 ++-
arch/arm/mach-s5pv210/mach-smdkv210.c | 393 +-
arch/arm/mach-s5pv210/setup-fb-24bpp.c | 1 -
arch/arm/mach-s5pv210/setup-keypad.c | 3 +-
arch/arm/mm/Kconfig | 10 +
arch/arm/mm/Makefile | 27 +-
arch/arm/mm/alignment.c | 7 +-
arch/arm/mm/cache-fa.S | 15 +-
arch/arm/mm/cache-l2x0.c | 1 +
arch/arm/mm/cache-v3.S | 15 +-
arch/arm/mm/cache-v4.S | 15 +-
arch/arm/mm/cache-v4wb.S | 15 +-
arch/arm/mm/cache-v4wt.S | 15 +-
arch/arm/mm/cache-v6.S | 15 +-
arch/arm/mm/cache-v7.S | 15 +-
arch/arm/mm/fault.c | 39 +-
arch/arm/mm/ioremap.c | 3 +-
arch/arm/mm/mm.h | 14 +
arch/arm/mm/proc-arm1020.S | 45 +-
arch/arm/mm/proc-arm1020e.S | 52 +-
arch/arm/mm/proc-arm1022.S | 52 +-
arch/arm/mm/proc-arm1026.S | 53 +-
arch/arm/mm/proc-arm6_7.S | 166 +-
arch/arm/mm/proc-arm720.S | 85 +-
arch/arm/mm/proc-arm740.S | 42 +-
arch/arm/mm/proc-arm7tdmi.S | 216 +-
arch/arm/mm/proc-arm920.S | 53 +-
arch/arm/mm/proc-arm922.S | 53 +-
arch/arm/mm/proc-arm925.S | 88 +-
arch/arm/mm/proc-arm926.S | 51 +-
arch/arm/mm/proc-arm940.S | 51 +-
arch/arm/mm/proc-arm946.S | 53 +-
arch/arm/mm/proc-arm9tdmi.S | 78 +-
arch/arm/mm/proc-fa526.S | 38 +-
arch/arm/mm/proc-feroceon.S | 202 +-
arch/arm/mm/proc-macros.S | 63 +
arch/arm/mm/proc-mohawk.S | 61 +-
arch/arm/mm/proc-sa110.S | 39 +-
arch/arm/mm/proc-sa1100.S | 84 +-
arch/arm/mm/proc-v6.S | 39 +-
arch/arm/mm/proc-v7.S | 222 +-
arch/arm/mm/proc-xsc3.S | 90 +-
arch/arm/mm/proc-xscale.S | 507 +-
arch/arm/mm/tlb-fa.S | 8 +-
arch/arm/mm/tlb-v3.S | 8 +-
arch/arm/mm/tlb-v4.S | 8 +-
arch/arm/mm/tlb-v4wb.S | 8 +-
arch/arm/mm/tlb-v4wbi.S | 8 +-
arch/arm/mm/tlb-v6.S | 8 +-
arch/arm/mm/tlb-v7.S | 9 +-
arch/arm/plat-s3c24xx/cpu.c | 9 +-
arch/arm/plat-s3c24xx/devs.c | 38 +-
arch/arm/plat-s5p/Kconfig | 193 +-
arch/arm/plat-s5p/Makefile | 32 +-
arch/arm/plat-s5p/clock.c | 42 +
arch/arm/plat-s5p/cpu.c | 72 +-
arch/arm/plat-s5p/dev-csis0.c | 15 +-
arch/arm/plat-s5p/dev-csis1.c | 15 +-
arch/arm/plat-s5p/dev-ehci.c | 58 +
arch/arm/plat-s5p/dev-fimc0.c | 3 +
arch/arm/plat-s5p/dev-fimc1.c | 3 +
arch/arm/plat-s5p/dev-fimc2.c | 3 +
arch/arm/plat-s5p/dev-fimc3.c | 3 +
arch/arm/plat-s5p/dev-pmu.c | 41 +-
arch/arm/plat-s5p/include/plat/ehci.h | 20 +
arch/arm/plat-s5p/include/plat/exynos4.h | 20 +-
arch/arm/plat-s5p/include/plat/irqs.h | 4 +
arch/arm/plat-s5p/include/plat/map-s5p.h | 28 +-
arch/arm/plat-s5p/include/plat/mipi_csis.h | 2 +
arch/arm/plat-s5p/include/plat/pll.h | 56 +-
arch/arm/plat-s5p/include/plat/s5p-clock.h | 8 +
arch/arm/plat-s5p/include/plat/system-reset.h | 18 +-
arch/arm/plat-s5p/include/plat/usb-phy.h | 13 +
arch/arm/plat-s5p/irq-eint.c | 22 +-
arch/arm/plat-s5p/irq-gpioint.c | 97 +-
arch/arm/plat-samsung/Kconfig | 98 +-
arch/arm/plat-samsung/Makefile | 10 +-
arch/arm/plat-samsung/adc.c | 271 +-
arch/arm/plat-samsung/clock.c | 131 +-
arch/arm/plat-samsung/dev-adc.c | 4 +-
arch/arm/plat-samsung/dev-asocdma.c | 14 +
arch/arm/plat-samsung/dev-fb.c | 14 +-
arch/arm/plat-samsung/dev-hsmmc.c | 3 +
arch/arm/plat-samsung/dev-hsmmc1.c | 1 +
arch/arm/plat-samsung/dev-hsmmc2.c | 8 +
arch/arm/plat-samsung/dev-hsmmc3.c | 7 +
arch/arm/plat-samsung/dev-hwmon.c | 14 +-
arch/arm/plat-samsung/dev-i2c0.c | 16 +-
arch/arm/plat-samsung/dev-i2c1.c | 24 +-
arch/arm/plat-samsung/dev-i2c2.c | 24 +-
arch/arm/plat-samsung/dev-i2c3.c | 24 +-
arch/arm/plat-samsung/dev-i2c4.c | 24 +-
arch/arm/plat-samsung/dev-i2c5.c | 24 +-
arch/arm/plat-samsung/dev-i2c6.c | 24 +-
arch/arm/plat-samsung/dev-i2c7.c | 24 +-
arch/arm/plat-samsung/dev-keypad.c | 4 +
arch/arm/plat-samsung/dev-nand.c | 9 +-
arch/arm/plat-samsung/dev-pwm.c | 93 +-
arch/arm/plat-samsung/dev-ts.c | 16 +-
arch/arm/plat-samsung/dev-usb.c | 9 +-
arch/arm/plat-samsung/dev-wdt.c | 2 +-
arch/arm/plat-samsung/gpio-config.c | 96 +
arch/arm/plat-samsung/include/plat/adc.h | 3 +-
arch/arm/plat-samsung/include/plat/audio.h | 6 +
arch/arm/plat-samsung/include/plat/clock.h | 12 +
arch/arm/plat-samsung/include/plat/cpu.h | 146 +-
arch/arm/plat-samsung/include/plat/devs.h | 120 +-
arch/arm/plat-samsung/include/plat/dma.h | 18 +-
arch/arm/plat-samsung/include/plat/fb-core.h | 21 +
arch/arm/plat-samsung/include/plat/fb.h | 63 +
arch/arm/plat-samsung/include/plat/gpio-cfg.h | 81 +-
arch/arm/plat-samsung/include/plat/gpio-core.h | 9 +-
arch/arm/plat-samsung/include/plat/iic.h | 3 +
arch/arm/plat-samsung/include/plat/keypad.h | 6 +-
arch/arm/plat-samsung/include/plat/map-base.h | 14 +-
arch/arm/plat-samsung/include/plat/pd.h | 37 +-
arch/arm/plat-samsung/include/plat/pm.h | 18 +-
arch/arm/plat-samsung/include/plat/regs-adc.h | 3 +
arch/arm/plat-samsung/include/plat/regs-fb-v4.h | 11 +
arch/arm/plat-samsung/include/plat/regs-fb.h | 117 +-
arch/arm/plat-samsung/include/plat/regs-serial.h | 6 +-
arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h | 22 +
arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | 1 +
arch/arm/plat-samsung/include/plat/sdhci.h | 67 +
arch/arm/plat-samsung/include/plat/ts.h | 6 +
arch/arm/plat-samsung/include/plat/udc-hs.h | 11 +
arch/arm/plat-samsung/include/plat/watchdog-reset.h | 12 +-
arch/arm/plat-samsung/irq-uart.c | 11 +
arch/arm/plat-samsung/irq-vic-timer.c | 5 +
arch/arm/plat-samsung/pd.c | 42 +-
arch/arm/plat-samsung/pm-gpio.c | 33 +-
arch/arm/plat-samsung/pm.c | 112 +-
arch/arm/plat-samsung/pwm.c | 103 +-
arch/arm/plat-samsung/s3c-pl330.c | 109 +-
arch/arm/tools/mach-types | 14 +-
arch/arm/vfp/vfpmodule.c | 15 +-
block/Kconfig.iosched | 14 +
block/Makefile | 1 +
block/blk-cgroup.c | 5 +-
block/blk-ioc.c | 4 +
block/blk-settings.c | 4 +
block/cfq-iosched.c | 5 +
block/deadline-iosched.c | 4 +
block/genhd.c | 26 +-
block/noop-iosched.c | 4 +
crypto/Kconfig | 23 +-
crypto/Makefile | 5 +
crypto/ablkcipher.c | 15 +
crypto/ahash.c | 30 +
crypto/algapi.c | 59 +-
crypto/ansi_cprng.c | 19 +-
crypto/api.c | 22 +
crypto/internal.h | 8 +-
crypto/proc.c | 12 +-
crypto/shash.c | 65 +
crypto/tcrypt.c | 160 +-
crypto/testmgr.c | 92 +-
drivers/Kconfig | 35 +
drivers/Makefile | 33 +-
drivers/base/Kconfig | 99 +
drivers/base/Makefile | 4 +-
drivers/base/core.c | 14 +
drivers/base/platform.c | 5 +-
drivers/base/power/main.c | 69 +-
drivers/base/power/opp.c | 32 +-
drivers/base/power/runtime.c | 3 +
drivers/bluetooth/hci_ldisc.c | 164 +-
drivers/char/Kconfig | 18 +
drivers/char/Makefile | 5 +
drivers/char/mem.c | 75 +-
drivers/cpufreq/Kconfig | 79 +
drivers/cpufreq/Makefile | 5 +
drivers/cpufreq/cpufreq.c | 2 +-
drivers/cpufreq/cpufreq_conservative.c | 12 +-
drivers/cpufreq/cpufreq_interactive.c | 9 +-
drivers/cpufreq/cpufreq_ondemand.c | 503 +-
drivers/crypto/Kconfig | 55 +
drivers/crypto/Makefile | 1 +
drivers/gpio/Kconfig | 6 +-
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-exynos4.c | 467 +-
drivers/gpio/gpio-plat-samsung.c | 39 +-
drivers/gpu/Makefile | 7 +-
drivers/gpu/drm/Kconfig | 28 +-
drivers/gpu/drm/Makefile | 14 +-
drivers/gpu/drm/drm_context.c | 5 +-
drivers/gpu/drm/drm_crtc.c | 1439 ++++--
drivers/gpu/drm/drm_crtc_helper.c | 121 +-
drivers/gpu/drm/drm_debugfs.c | 15 +-
drivers/gpu/drm/drm_drv.c | 42 +-
drivers/gpu/drm/drm_edid.c | 261 +-
drivers/gpu/drm/drm_edid_modes.h | 284 ++
drivers/gpu/drm/drm_encoder_slave.c | 2 +
drivers/gpu/drm/drm_fb_helper.c | 97 +-
drivers/gpu/drm/drm_fops.c | 11 +-
drivers/gpu/drm/drm_gem.c | 150 +-
drivers/gpu/drm/drm_ioc32.c | 3 +-
drivers/gpu/drm/drm_ioctl.c | 22 +-
drivers/gpu/drm/drm_irq.c | 61 +-
drivers/gpu/drm/drm_lock.c | 2 +
drivers/gpu/drm/drm_memory.c | 19 -
drivers/gpu/drm/drm_modes.c | 117 +-
drivers/gpu/drm/drm_pci.c | 2 -
drivers/gpu/drm/drm_platform.c | 15 +-
drivers/gpu/drm/drm_proc.c | 3 +-
drivers/gpu/drm/drm_scatter.c | 10 +-
drivers/gpu/drm/drm_stub.c | 26 +
drivers/gpu/drm/drm_sysfs.c | 9 +-
drivers/gpu/drm/drm_usb.c | 2 -
drivers/gpu/drm/drm_vm.c | 5 +-
drivers/gpu/drm/i2c/ch7006_drv.c | 7 +-
drivers/gpu/drm/i2c/sil164_drv.c | 2 +
drivers/gpu/drm/i810/i810_dma.c | 5 +-
drivers/gpu/drm/i810/i810_drv.c | 25 +-
drivers/gpu/drm/i915/Makefile | 3 +-
drivers/gpu/drm/i915/dvo_ch7017.c | 2 +-
drivers/gpu/drm/i915/dvo_ch7xxx.c | 4 +-
drivers/gpu/drm/i915/dvo_ivch.c | 6 +-
drivers/gpu/drm/i915/dvo_sil164.c | 2 +-
drivers/gpu/drm/i915/dvo_tfp410.c | 14 +-
drivers/gpu/drm/i915/i915_debugfs.c | 670 ++-
drivers/gpu/drm/i915/i915_dma.c | 125 +-
drivers/gpu/drm/i915/i915_drv.c | 283 +-
drivers/gpu/drm/i915/i915_drv.h | 353 +-
drivers/gpu/drm/i915/i915_gem.c | 848 ++--
drivers/gpu/drm/i915/i915_gem_debug.c | 8 +-
drivers/gpu/drm/i915/i915_gem_evict.c | 23 +-
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 290 +-
drivers/gpu/drm/i915/i915_gem_gtt.c | 342 +-
drivers/gpu/drm/i915/i915_gem_tiling.c | 34 +-
drivers/gpu/drm/i915/i915_irq.c | 266 +-
drivers/gpu/drm/i915/i915_reg.h | 498 +-
drivers/gpu/drm/i915/i915_suspend.c | 24 +-
drivers/gpu/drm/i915/i915_trace.h | 46 +-
drivers/gpu/drm/i915/intel_acpi.c | 4 +-
drivers/gpu/drm/i915/intel_bios.c | 169 +-
drivers/gpu/drm/i915/intel_bios.h | 28 +-
drivers/gpu/drm/i915/intel_crt.c | 48 +-
drivers/gpu/drm/i915/intel_display.c | 2445 ++++++---
drivers/gpu/drm/i915/intel_dp.c | 1093 +++--
drivers/gpu/drm/i915/intel_drv.h | 106 +-
drivers/gpu/drm/i915/intel_dvo.c | 1 -
drivers/gpu/drm/i915/intel_fb.c | 25 +-
drivers/gpu/drm/i915/intel_hdmi.c | 208 +-
drivers/gpu/drm/i915/intel_i2c.c | 218 +-
drivers/gpu/drm/i915/intel_lvds.c | 145 +-
drivers/gpu/drm/i915/intel_modes.c | 36 +-
drivers/gpu/drm/i915/intel_opregion.c | 106 +-
drivers/gpu/drm/i915/intel_overlay.c | 170 +-
drivers/gpu/drm/i915/intel_panel.c | 101 +-
drivers/gpu/drm/i915/intel_ringbuffer.c | 624 ++-
drivers/gpu/drm/i915/intel_ringbuffer.h | 43 +-
drivers/gpu/drm/i915/intel_sdvo.c | 416 +-
drivers/gpu/drm/i915/intel_sdvo_regs.h | 560 +--
drivers/gpu/drm/i915/intel_tv.c | 210 +-
drivers/gpu/drm/mga/mga_dma.c | 2 +
drivers/gpu/drm/mga/mga_drv.c | 31 +-
drivers/gpu/drm/mga/mga_warp.c | 1 +
drivers/gpu/drm/nouveau/Makefile | 21 +-
drivers/gpu/drm/nouveau/nouveau_acpi.c | 79 +-
drivers/gpu/drm/nouveau/nouveau_backlight.c | 169 +-
drivers/gpu/drm/nouveau/nouveau_bios.c | 1390 ++----
drivers/gpu/drm/nouveau/nouveau_bios.h | 80 +-
drivers/gpu/drm/nouveau/nouveau_bo.c | 339 +-
drivers/gpu/drm/nouveau/nouveau_channel.c | 185 +-
drivers/gpu/drm/nouveau/nouveau_connector.c | 504 +-
drivers/gpu/drm/nouveau/nouveau_connector.h | 36 +-
drivers/gpu/drm/nouveau/nouveau_crtc.h | 12 +-
drivers/gpu/drm/nouveau/nouveau_debugfs.c | 3 +-
drivers/gpu/drm/nouveau/nouveau_display.c | 269 +-
drivers/gpu/drm/nouveau/nouveau_dma.c | 21 +-
drivers/gpu/drm/nouveau/nouveau_dp.c | 831 ++--
drivers/gpu/drm/nouveau/nouveau_drv.c | 120 +-
drivers/gpu/drm/nouveau/nouveau_drv.h | 410 +-
drivers/gpu/drm/nouveau/nouveau_encoder.h | 43 +-
drivers/gpu/drm/nouveau/nouveau_fb.h | 5 +-
drivers/gpu/drm/nouveau/nouveau_fbcon.c | 54 +-
drivers/gpu/drm/nouveau/nouveau_fence.c | 34 +-
drivers/gpu/drm/nouveau/nouveau_gem.c | 148 +-
drivers/gpu/drm/nouveau/nouveau_i2c.c | 542 +-
drivers/gpu/drm/nouveau/nouveau_i2c.h | 21 +-
drivers/gpu/drm/nouveau/nouveau_irq.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_mem.c | 956 ++--
drivers/gpu/drm/nouveau/nouveau_mm.c | 88 +-
drivers/gpu/drm/nouveau/nouveau_mm.h | 6 +-
drivers/gpu/drm/nouveau/nouveau_notifier.c | 22 +-
drivers/gpu/drm/nouveau/nouveau_object.c | 107 +-
drivers/gpu/drm/nouveau/nouveau_perf.c | 423 +-
drivers/gpu/drm/nouveau/nouveau_pm.c | 605 ++-
drivers/gpu/drm/nouveau/nouveau_pm.h | 57 +-
drivers/gpu/drm/nouveau/nouveau_reg.h | 11 +-
drivers/gpu/drm/nouveau/nouveau_sgdma.c | 206 +-
drivers/gpu/drm/nouveau/nouveau_state.c | 635 ++-
drivers/gpu/drm/nouveau/nouveau_temp.c | 46 +-
drivers/gpu/drm/nouveau/nouveau_vm.c | 64 +-
drivers/gpu/drm/nouveau/nouveau_vm.h | 6 +-
drivers/gpu/drm/nouveau/nouveau_volt.c | 61 +-
drivers/gpu/drm/nouveau/nv04_crtc.c | 31 +-
drivers/gpu/drm/nouveau/nv04_dac.c | 14 +-
drivers/gpu/drm/nouveau/nv04_dfp.c | 16 +-
drivers/gpu/drm/nouveau/nv04_display.c | 28 +-
drivers/gpu/drm/nouveau/nv04_fb.c | 34 +
drivers/gpu/drm/nouveau/nv04_graph.c | 22 +-
drivers/gpu/drm/nouveau/nv04_instmem.c | 28 +-
drivers/gpu/drm/nouveau/nv04_pm.c | 107 +-
drivers/gpu/drm/nouveau/nv04_timer.c | 85 +-
drivers/gpu/drm/nouveau/nv10_fb.c | 126 +-
drivers/gpu/drm/nouveau/nv10_gpio.c | 117 +-
drivers/gpu/drm/nouveau/nv10_graph.c | 15 +-
drivers/gpu/drm/nouveau/nv17_tv.c | 20 +-
drivers/gpu/drm/nouveau/nv20_graph.c | 13 +-
drivers/gpu/drm/nouveau/nv40_fb.c | 45 +
drivers/gpu/drm/nouveau/nv40_graph.c | 112 +-
drivers/gpu/drm/nouveau/nv50_crtc.c | 391 +-
drivers/gpu/drm/nouveau/nv50_cursor.c | 18 -
drivers/gpu/drm/nouveau/nv50_dac.c | 14 +-
drivers/gpu/drm/nouveau/nv50_display.c | 249 +-
drivers/gpu/drm/nouveau/nv50_display.h | 6 +
drivers/gpu/drm/nouveau/nv50_evo.c | 22 +-
drivers/gpu/drm/nouveau/nv50_evo.h | 3 +-
drivers/gpu/drm/nouveau/nv50_fbcon.c | 10 +-
drivers/gpu/drm/nouveau/nv50_fifo.c | 6 +-
drivers/gpu/drm/nouveau/nv50_gpio.c | 247 +-
drivers/gpu/drm/nouveau/nv50_graph.c | 132 +-
drivers/gpu/drm/nouveau/nv50_grctx.c | 13 +-
drivers/gpu/drm/nouveau/nv50_instmem.c | 8 +-
drivers/gpu/drm/nouveau/nv50_mpeg.c | 2 +-
drivers/gpu/drm/nouveau/nv50_pm.c | 900 +++-
drivers/gpu/drm/nouveau/nv50_sor.c | 275 +-
drivers/gpu/drm/nouveau/nv50_vm.c | 33 +-
drivers/gpu/drm/nouveau/nv50_vram.c | 60 +-
drivers/gpu/drm/nouveau/nv84_crypt.c | 2 +-
drivers/gpu/drm/nouveau/nva3_copy.c | 2 +-
drivers/gpu/drm/nouveau/nva3_copy.fuc | 262 +-
drivers/gpu/drm/nouveau/nva3_copy.fuc.h | 2 +-
drivers/gpu/drm/nouveau/nva3_pm.c | 408 +-
drivers/gpu/drm/nouveau/nvc0_copy.c | 8 +-
drivers/gpu/drm/nouveau/nvc0_copy.fuc.h | 2 +-
drivers/gpu/drm/nouveau/nvc0_fb.c | 95 +-
drivers/gpu/drm/nouveau/nvc0_fbcon.c | 14 +-
drivers/gpu/drm/nouveau/nvc0_fifo.c | 6 +-
drivers/gpu/drm/nouveau/nvc0_graph.c | 356 +-
drivers/gpu/drm/nouveau/nvc0_graph.h | 26 +-
drivers/gpu/drm/nouveau/nvc0_grctx.c | 360 +-
drivers/gpu/drm/nouveau/nvc0_instmem.c | 14 +-
drivers/gpu/drm/nouveau/nvc0_vm.c | 10 +-
drivers/gpu/drm/nouveau/nvc0_vram.c | 61 +-
drivers/gpu/drm/r128/r128_cce.c | 1 +
drivers/gpu/drm/r128/r128_drv.c | 33 +-
drivers/gpu/drm/radeon/Makefile | 6 +-
drivers/gpu/drm/radeon/atom.c | 5 +
drivers/gpu/drm/radeon/atombios_crtc.c | 162 +-
drivers/gpu/drm/radeon/atombios_dp.c | 48 +-
drivers/gpu/drm/radeon/evergreen.c | 422 +-
drivers/gpu/drm/radeon/evergreen_blit_kms.c | 614 +--
drivers/gpu/drm/radeon/evergreen_cs.c | 1657 ++++++-
drivers/gpu/drm/radeon/evergreen_reg.h | 43 +
drivers/gpu/drm/radeon/evergreend.h | 518 +-
drivers/gpu/drm/radeon/ni.c | 445 +-
drivers/gpu/drm/radeon/nid.h | 36 +
drivers/gpu/drm/radeon/r100.c | 475 +-
drivers/gpu/drm/radeon/r100_track.h | 110 +-
drivers/gpu/drm/radeon/r200.c | 50 +-
drivers/gpu/drm/radeon/r300.c | 282 +-
drivers/gpu/drm/radeon/r300_cmdbuf.c | 2 +-
drivers/gpu/drm/radeon/r420.c | 57 +-
drivers/gpu/drm/radeon/r500_reg.h | 4 +
drivers/gpu/drm/radeon/r520.c | 35 +-
drivers/gpu/drm/radeon/r600.c | 531 +-
drivers/gpu/drm/radeon/r600_audio.c | 57 +-
drivers/gpu/drm/radeon/r600_blit.c | 24 +-
drivers/gpu/drm/radeon/r600_blit_kms.c | 642 ++-
drivers/gpu/drm/radeon/r600_cp.c | 27 +-
drivers/gpu/drm/radeon/r600_cs.c | 697 ++-
drivers/gpu/drm/radeon/r600_hdmi.c | 58 +-
drivers/gpu/drm/radeon/r600d.h | 45 +
drivers/gpu/drm/radeon/radeon.h | 797 ++-
drivers/gpu/drm/radeon/radeon_acpi.c | 11 +-
drivers/gpu/drm/radeon/radeon_asic.c | 1700 ++++---
drivers/gpu/drm/radeon/radeon_asic.h | 83 +-
drivers/gpu/drm/radeon/radeon_atombios.c | 352 +-
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 3 +-
drivers/gpu/drm/radeon/radeon_benchmark.c | 249 +-
drivers/gpu/drm/radeon/radeon_bios.c | 2 +-
drivers/gpu/drm/radeon/radeon_clocks.c | 6 +-
drivers/gpu/drm/radeon/radeon_combios.c | 48 +-
drivers/gpu/drm/radeon/radeon_connectors.c | 178 +-
drivers/gpu/drm/radeon/radeon_cp.c | 6 +-
drivers/gpu/drm/radeon/radeon_cs.c | 304 +-
drivers/gpu/drm/radeon/radeon_cursor.c | 35 +-
drivers/gpu/drm/radeon/radeon_device.c | 117 +-
drivers/gpu/drm/radeon/radeon_display.c | 221 +-
drivers/gpu/drm/radeon/radeon_drv.c | 75 +-
drivers/gpu/drm/radeon/radeon_encoders.c | 2138 +-------
drivers/gpu/drm/radeon/radeon_fb.c | 46 +-
drivers/gpu/drm/radeon/radeon_fence.c | 313 +-
drivers/gpu/drm/radeon/radeon_gart.c | 498 +-
drivers/gpu/drm/radeon/radeon_gem.c | 173 +-
drivers/gpu/drm/radeon/radeon_i2c.c | 111 +-
drivers/gpu/drm/radeon/radeon_irq.c | 2 +-
drivers/gpu/drm/radeon/radeon_irq_kms.c | 36 +-
drivers/gpu/drm/radeon/radeon_kms.c | 64 +-
drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 12 +-
drivers/gpu/drm/radeon/radeon_legacy_tv.c | 2 +-
drivers/gpu/drm/radeon/radeon_mem.c | 3 +-
drivers/gpu/drm/radeon/radeon_mode.h | 26 +-
drivers/gpu/drm/radeon/radeon_object.c | 125 +-
drivers/gpu/drm/radeon/radeon_object.h | 74 +-
drivers/gpu/drm/radeon/radeon_pm.c | 58 +-
drivers/gpu/drm/radeon/radeon_reg.h | 4 +-
drivers/gpu/drm/radeon/radeon_ring.c | 501 +-
drivers/gpu/drm/radeon/radeon_state.c | 16 +-
drivers/gpu/drm/radeon/radeon_test.c | 301 +-
drivers/gpu/drm/radeon/radeon_ttm.c | 379 +-
drivers/gpu/drm/radeon/reg_srcs/cayman | 26 +-
drivers/gpu/drm/radeon/reg_srcs/evergreen | 27 +-
drivers/gpu/drm/radeon/reg_srcs/r600 | 21 +-
drivers/gpu/drm/radeon/rs400.c | 43 +-
drivers/gpu/drm/radeon/rs600.c | 97 +-
drivers/gpu/drm/radeon/rs690.c | 40 +-
drivers/gpu/drm/radeon/rv515.c | 115 +-
drivers/gpu/drm/radeon/rv770.c | 153 +-
drivers/gpu/drm/savage/savage_drv.c | 25 +-
drivers/gpu/drm/savage/savage_state.c | 5 +-
drivers/gpu/drm/sis/sis_drv.c | 63 +-
drivers/gpu/drm/sis/sis_drv.h | 11 +-
drivers/gpu/drm/sis/sis_mm.c | 199 +-
drivers/gpu/drm/tdfx/tdfx_drv.c | 25 +-
drivers/gpu/drm/ttm/Makefile | 4 +
drivers/gpu/drm/ttm/ttm_agp_backend.c | 109 +-
drivers/gpu/drm/ttm/ttm_bo.c | 176 +-
drivers/gpu/drm/ttm/ttm_bo_util.c | 34 +-
drivers/gpu/drm/ttm/ttm_bo_vm.c | 14 +-
drivers/gpu/drm/ttm/ttm_lock.c | 2 +-
drivers/gpu/drm/ttm/ttm_memory.c | 14 +-
drivers/gpu/drm/ttm/ttm_object.c | 7 +-
drivers/gpu/drm/ttm/ttm_page_alloc.c | 245 +-
drivers/gpu/drm/ttm/ttm_tt.c | 330 +-
drivers/gpu/drm/via/via_drv.c | 50 +-
drivers/gpu/drm/via/via_drv.h | 7 +-
drivers/gpu/drm/via/via_map.c | 12 +-
drivers/gpu/drm/via/via_mm.c | 135 +-
drivers/gpu/drm/vmwgfx/Kconfig | 9 +-
drivers/gpu/drm/vmwgfx/Makefile | 3 +-
drivers/gpu/drm/vmwgfx/svga3d_reg.h | 259 +-
drivers/gpu/drm/vmwgfx/svga_escape.h | 2 +-
drivers/gpu/drm/vmwgfx/svga_overlay.h | 22 +-
drivers/gpu/drm/vmwgfx/svga_reg.h | 304 +-
drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 142 +-
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 360 +-
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 236 +-
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 879 +++-
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 96 +-
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 1163 ++++-
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 164 +-
drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 81 +-
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 46 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 273 +-
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 187 +-
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 1524 ++++--
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 64 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 334 +-
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 191 +-
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 1101 ++++-
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 5 +-
drivers/gpu/ion/Kconfig | 16 +
drivers/gpu/ion/Makefile | 1 +
drivers/gpu/ion/ion.c | 212 +-
drivers/hid/Kconfig | 2 +-
drivers/hid/hid-core.c | 3 +
drivers/hid/hid-ids.h | 2 +
drivers/hid/hid-samsung.c | 59 +
drivers/hwmon/Kconfig | 14 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/hwmon.c | 350 ++
drivers/hwmon/sht21.c | 1 +
drivers/i2c/busses/i2c-gpio.c | 4 +
drivers/i2c/busses/i2c-s3c2410.c | 133 +-
drivers/input/Kconfig | 24 +
drivers/input/Makefile | 2 +
drivers/input/evdev.c | 5 +
drivers/input/input.c | 8 +-
drivers/input/keyboard/Kconfig | 2 +
drivers/input/keyboard/Makefile | 5 +
drivers/input/keyboard/gpio_keys.c | 365 +-
drivers/input/keyboard/samsung-keypad.c | 218 +-
drivers/input/misc/Kconfig | 36 +-
drivers/input/misc/Makefile | 6 +-
drivers/input/touchscreen/Kconfig | 269 +-
drivers/input/touchscreen/Makefile | 34 +-
drivers/input/touchscreen/s3c2410_ts.c | 134 +-
drivers/leds/Kconfig | 56 +
drivers/leds/Makefile | 5 +
drivers/leds/leds-lp5521.c | 294 +-
drivers/md/dm-crypt.c | 9 +-
drivers/media/Kconfig | 9 +
drivers/media/Makefile | 2 +
drivers/media/radio/si470x/Kconfig | 13 +
drivers/media/radio/si470x/Makefile | 2 +
drivers/media/rc/rc-main.c | 3 +-
drivers/media/video/Kconfig | 383 +-
drivers/media/video/Makefile | 33 +
drivers/media/video/m5mols/Kconfig | 3 +-
drivers/media/video/m5mols/Makefile | 2 +-
drivers/media/video/m5mols/m5mols.h | 565 ++-
drivers/media/video/m5mols/m5mols_controls.c | 369 +-
drivers/media/video/m5mols/m5mols_core.c | 1793 ++++---
drivers/media/video/m5mols/m5mols_reg.h | 390 +-
drivers/media/video/s5p-fimc/Makefile | 5 +-
drivers/media/video/s5p-fimc/fimc-capture.c | 863 +++-
drivers/media/video/s5p-fimc/fimc-core.c | 1020 +++-
drivers/media/video/s5p-fimc/fimc-core.h | 177 +-
drivers/media/video/s5p-fimc/fimc-reg.c | 255 +-
drivers/media/video/s5p-fimc/regs-fimc.h | 36 +-
drivers/media/video/v4l2-common.c | 26 +
drivers/media/video/v4l2-ctrls.c | 15 +
drivers/media/video/v4l2-fh.c | 2 +
drivers/media/video/v4l2-ioctl.c | 37 +-
drivers/media/video/v4l2-mem2mem.c | 32 +-
drivers/media/video/videobuf-core.c | 4 +
drivers/media/video/videobuf2-core.c | 216 +-
drivers/media/video/videobuf2-dma-contig.c | 135 +-
drivers/mfd/Kconfig | 42 +
drivers/mfd/Makefile | 8 +-
drivers/mfd/max8997-irq.c | 558 ++-
drivers/mfd/max8997.c | 298 +-
drivers/mfd/wm8994-core.c | 267 +-
drivers/mfd/wm8994-irq.c | 16 +-
drivers/misc/Kconfig | 230 +-
drivers/misc/Makefile | 44 +-
drivers/mmc/card/Kconfig | 12 +
drivers/mmc/card/Makefile | 4 +-
drivers/mmc/card/block.c | 1463 +++++-
drivers/mmc/card/queue.c | 278 +-
drivers/mmc/card/queue.h | 64 +-
drivers/mmc/core/Kconfig | 13 +
drivers/mmc/core/bus.c | 5 +-
drivers/mmc/core/core.c | 733 ++-
drivers/mmc/core/core.h | 3 +
drivers/mmc/core/debugfs.c | 12 +
drivers/mmc/core/host.c | 61 +-
drivers/mmc/core/host.h | 21 -
drivers/mmc/core/mmc.c | 666 ++-
drivers/mmc/core/mmc_ops.c | 42 +
drivers/mmc/core/mmc_ops.h | 1 +
drivers/mmc/core/quirks.c | 25 +
drivers/mmc/core/sd.c | 130 +-
drivers/mmc/core/sdio.c | 365 +-
drivers/mmc/core/sdio_io.c | 3 +
drivers/mmc/core/sdio_irq.c | 10 +-
drivers/mmc/host/Kconfig | 41 +
drivers/mmc/host/Makefile | 5 +-
drivers/mmc/host/dw_mmc.c | 803 ++-
drivers/mmc/host/dw_mmc.h | 20 +-
drivers/mmc/host/sdhci-s3c.c | 215 +-
drivers/mmc/host/sdhci.c | 278 +-
drivers/mmc/host/sdhci.h | 4 +-
drivers/net/Kconfig | 2 +
drivers/net/Makefile | 3 +
drivers/net/usb/Kconfig | 10 +
drivers/net/usb/Makefile | 3 +-
drivers/net/usb/usbnet.c | 135 +-
drivers/net/wireless/Kconfig | 5 +-
drivers/net/wireless/Makefile | 13 +-
drivers/net/wireless/ath/Kconfig | 1 +
drivers/net/wireless/ath/Makefile | 5 +
drivers/net/wireless/ath/ath.h | 49 +-
drivers/net/wireless/ath/debug.c | 1 +
drivers/net/wireless/ath/hw.c | 1 +
drivers/net/wireless/ath/key.c | 20 +-
drivers/net/wireless/ath/main.c | 17 +-
drivers/net/wireless/ath/regd.c | 84 +-
drivers/net/wireless/ath/regd.h | 2 +-
drivers/net/wireless/ath/regd_common.h | 2 +-
drivers/net/wireless/bcmdhd/Kconfig | 50 +-
drivers/net/wireless/bcmdhd/Makefile | 251 +-
drivers/net/wireless/bcmdhd/aiutils.c | 213 +-
drivers/net/wireless/bcmdhd/bcmevent.c | 35 +-
drivers/net/wireless/bcmdhd/bcmsdh.c | 112 +-
drivers/net/wireless/bcmdhd/bcmsdh_linux.c | 116 +-
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c | 177 +-
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 162 +-
drivers/net/wireless/bcmdhd/bcmutils.c | 629 ++-
drivers/net/wireless/bcmdhd/dhd.h | 208 +-
drivers/net/wireless/bcmdhd/dhd_bta.c | 11 +-
drivers/net/wireless/bcmdhd/dhd_bta.h | 6 +-
drivers/net/wireless/bcmdhd/dhd_bus.h | 20 +-
drivers/net/wireless/bcmdhd/dhd_cdc.c | 746 ++-
drivers/net/wireless/bcmdhd/dhd_cfg80211.c | 84 +-
drivers/net/wireless/bcmdhd/dhd_cfg80211.h | 5 +-
drivers/net/wireless/bcmdhd/dhd_common.c | 250 +-
drivers/net/wireless/bcmdhd/dhd_custom_gpio.c | 30 +-
drivers/net/wireless/bcmdhd/dhd_dbg.h | 35 +-
drivers/net/wireless/bcmdhd/dhd_linux.c | 1840 +++++--
drivers/net/wireless/bcmdhd/dhd_linux_sched.c | 6 +-
drivers/net/wireless/bcmdhd/dhd_proto.h | 20 +-
drivers/net/wireless/bcmdhd/dhd_sdio.c | 2173 +++++++-
drivers/net/wireless/bcmdhd/dhd_wlfc.h | 28 +-
drivers/net/wireless/bcmdhd/dngl_stats.h | 6 +-
drivers/net/wireless/bcmdhd/dngl_wlhdr.h | 6 +-
drivers/net/wireless/bcmdhd/hndpmu.c | 21 +-
drivers/net/wireless/bcmdhd/include/Makefile | 2 +-
drivers/net/wireless/bcmdhd/include/aidmp.h | 10 +-
drivers/net/wireless/bcmdhd/include/bcmcdc.h | 55 +-
drivers/net/wireless/bcmdhd/include/bcmdefs.h | 64 +-
drivers/net/wireless/bcmdhd/include/bcmdevs.h | 397 +-
drivers/net/wireless/bcmdhd/include/bcmendian.h | 7 +-
drivers/net/wireless/bcmdhd/include/bcmpcispi.h | 6 +-
drivers/net/wireless/bcmdhd/include/bcmperf.h | 6 +-
drivers/net/wireless/bcmdhd/include/bcmsdbus.h | 38 +-
drivers/net/wireless/bcmdhd/include/bcmsdh.h | 50 +-
drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h | 8 +-
drivers/net/wireless/bcmdhd/include/bcmsdpcm.h | 6 +-
drivers/net/wireless/bcmdhd/include/bcmsdspi.h | 6 +-
drivers/net/wireless/bcmdhd/include/bcmsdstd.h | 30 +-
drivers/net/wireless/bcmdhd/include/bcmspi.h | 6 +-
drivers/net/wireless/bcmdhd/include/bcmutils.h | 180 +-
drivers/net/wireless/bcmdhd/include/dhdioctl.h | 15 +-
drivers/net/wireless/bcmdhd/include/epivers.h | 34 +-
drivers/net/wireless/bcmdhd/include/hndpmu.h | 8 +-
drivers/net/wireless/bcmdhd/include/hndrte_armtrap.h | 38 +-
drivers/net/wireless/bcmdhd/include/hndrte_cons.h | 7 +-
drivers/net/wireless/bcmdhd/include/hndsoc.h | 36 +-
drivers/net/wireless/bcmdhd/include/linux_osl.h | 137 +-
drivers/net/wireless/bcmdhd/include/linuxver.h | 76 +-
drivers/net/wireless/bcmdhd/include/miniopt.h | 6 +-
drivers/net/wireless/bcmdhd/include/msgtrace.h | 8 +-
drivers/net/wireless/bcmdhd/include/osl.h | 30 +-
drivers/net/wireless/bcmdhd/include/packed_section_end.h | 7 +-
drivers/net/wireless/bcmdhd/include/packed_section_start.h | 9 +-
drivers/net/wireless/bcmdhd/include/pcicfg.h | 54 +-
drivers/net/wireless/bcmdhd/include/proto/802.11.h | 2292 +++++----
drivers/net/wireless/bcmdhd/include/proto/802.11_bta.h | 6 +-
drivers/net/wireless/bcmdhd/include/proto/802.11e.h | 12 +-
drivers/net/wireless/bcmdhd/include/proto/802.1d.h | 7 +-
drivers/net/wireless/bcmdhd/include/proto/bcmeth.h | 7 +-
drivers/net/wireless/bcmdhd/include/proto/bcmevent.h | 73 +-
drivers/net/wireless/bcmdhd/include/proto/bcmip.h | 64 +-
drivers/net/wireless/bcmdhd/include/proto/bt_amp_hci.h | 7 +-
drivers/net/wireless/bcmdhd/include/proto/eapol.h | 26 +-
drivers/net/wireless/bcmdhd/include/proto/ethernet.h | 25 +-
drivers/net/wireless/bcmdhd/include/proto/p2p.h | 701 +--
drivers/net/wireless/bcmdhd/include/proto/sdspi.h | 7 +-
drivers/net/wireless/bcmdhd/include/proto/vlan.h | 7 +-
drivers/net/wireless/bcmdhd/include/proto/wpa.h | 56 +-
drivers/net/wireless/bcmdhd/include/sbchipc.h | 682 ++-
drivers/net/wireless/bcmdhd/include/sbconfig.h | 7 +-
drivers/net/wireless/bcmdhd/include/sbhnddma.h | 67 +-
drivers/net/wireless/bcmdhd/include/sbpcmcia.h | 7 +-
drivers/net/wireless/bcmdhd/include/sbsdio.h | 31 +-
drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h | 8 +-
drivers/net/wireless/bcmdhd/include/sbsocram.h | 31 +-
drivers/net/wireless/bcmdhd/include/sdio.h | 15 +-
drivers/net/wireless/bcmdhd/include/sdioh.h | 11 +-
drivers/net/wireless/bcmdhd/include/sdiovar.h | 29 +-
drivers/net/wireless/bcmdhd/include/siutils.h | 75 +-
drivers/net/wireless/bcmdhd/include/trxhdr.h | 18 +-
drivers/net/wireless/bcmdhd/include/typedefs.h | 10 +-
drivers/net/wireless/bcmdhd/include/wlfc_proto.h | 76 +-
drivers/net/wireless/bcmdhd/include/wlioctl.h | 5834 +++++++++++++++-------
drivers/net/wireless/bcmdhd/linux_osl.c | 324 +-
drivers/net/wireless/bcmdhd/sbutils.c | 15 +-
drivers/net/wireless/bcmdhd/siutils.c | 740 ++-
drivers/net/wireless/bcmdhd/siutils_priv.h | 31 +-
drivers/net/wireless/bcmdhd/uamp_api.h | 6 +-
drivers/net/wireless/bcmdhd/wl_android.c | 1419 +++++-
drivers/net/wireless/bcmdhd/wl_android.h | 12 +-
drivers/net/wireless/bcmdhd/wl_cfg80211.c | 4840 +++++++++++++-----
drivers/net/wireless/bcmdhd/wl_cfg80211.h | 250 +-
drivers/net/wireless/bcmdhd/wl_cfgp2p.c | 791 ++-
drivers/net/wireless/bcmdhd/wl_cfgp2p.h | 101 +-
drivers/net/wireless/bcmdhd/wl_dbg.h | 30 +-
drivers/net/wireless/bcmdhd/wl_iw.c | 9553 +++++++++---------------------------
drivers/net/wireless/bcmdhd/wl_iw.h | 216 +-
drivers/net/wireless/bcmdhd/wl_linux_mon.c | 23 +-
drivers/net/wireless/bcmdhd/wldev_common.c | 102 +-
drivers/net/wireless/bcmdhd/wldev_common.h | 11 +-
drivers/nfc/Kconfig | 11 +
drivers/nfc/Makefile | 1 +
drivers/power/Kconfig | 107 +-
drivers/power/Makefile | 20 +
drivers/power/max17042_battery.c | 5 +-
drivers/power/power_supply_sysfs.c | 3 +
drivers/power/s3c_adc_battery.c | 16 +-
drivers/regulator/Kconfig | 48 +
drivers/regulator/Makefile | 6 +
drivers/regulator/core.c | 2 +-
drivers/regulator/fixed.c | 4 +
drivers/regulator/max8649.c | 54 +-
drivers/regulator/max8997.c | 1845 ++++---
drivers/regulator/wm8994-regulator.c | 46 +-
drivers/rtc/Kconfig | 64 +-
drivers/rtc/Makefile | 3 +
drivers/rtc/alarm-dev.c | 32 +-
drivers/rtc/alarm.c | 117 +
drivers/rtc/interface.c | 66 +
drivers/rtc/rtc-lib.c | 2 +
drivers/rtc/rtc-s3c.c | 307 +-
drivers/scsi/scsi_lib.c | 11 +
drivers/scsi/sd.c | 143 +
drivers/scsi/sd.h | 8 +
drivers/spi/Kconfig | 2 +-
drivers/spi/spi_s3c64xx.c | 66 +-
drivers/staging/android/binder.c | 41 +-
drivers/staging/android/logger.c | 41 +-
drivers/staging/android/logger.h | 1 +
drivers/staging/android/lowmemorykiller.c | 360 +-
drivers/staging/android/ram_console.c | 8 +-
drivers/staging/gma500/psb_drv.c | 23 +-
drivers/staging/gma500/psb_fb.c | 2 +-
drivers/staging/iio/gyro/Kconfig | 10 +
drivers/staging/iio/gyro/Makefile | 3 +
drivers/staging/westbridge/Kconfig | 7 +
drivers/staging/westbridge/astoria/Kconfig | 3 +
drivers/staging/westbridge/astoria/Makefile | 9 +-
drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c | 36 +-
drivers/staging/westbridge/astoria/api/src/cyasmisc.c | 12 +-
drivers/staging/westbridge/astoria/api/src/cyasstorage.c | 96 +-
drivers/staging/westbridge/astoria/block/Makefile | 2 +-
drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h | 6 +
drivers/staging/westbridge/astoria/device/Kconfig | 1 +
drivers/staging/westbridge/astoria/device/Makefile | 23 +-
drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h | 16 +-
drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h | 10 +-
drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h | 29 +
drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h | 64 +-
drivers/staging/zram/Kconfig | 7 +
drivers/staging/zram/zram_drv.c | 53 +-
drivers/staging/zram/zram_drv.h | 2 +-
drivers/staging/zram/zram_sysfs.c | 40 +-
drivers/switch/switch_class.c | 12 +
drivers/thermal/Kconfig | 30 +
drivers/thermal/Makefile | 3 +
drivers/thermal/thermal_sys.c | 31 +-
drivers/tty/serial/8250.c | 2 +-
drivers/tty/serial/Kconfig | 20 +-
drivers/tty/serial/s5pv210.c | 14 +-
drivers/tty/serial/samsung.c | 367 +-
drivers/tty/serial/samsung.h | 19 -
drivers/tty/serial/serial_core.c | 19 +-
drivers/usb/Kconfig | 10 +
drivers/usb/Makefile | 1 +
drivers/usb/core/Kconfig | 19 +
drivers/usb/core/devio.c | 10 +-
drivers/usb/core/driver.c | 19 +
drivers/usb/core/hub.c | 120 +-
drivers/usb/core/message.c | 24 +-
drivers/usb/core/quirks.c | 19 +
drivers/usb/gadget/Kconfig | 162 +
drivers/usb/gadget/Makefile | 11 +
drivers/usb/gadget/android.c | 588 ++-
drivers/usb/gadget/composite.c | 331 +-
drivers/usb/gadget/epautoconf.c | 61 +-
drivers/usb/gadget/ether.c | 4 +-
drivers/usb/gadget/f_accessory.c | 402 +-
drivers/usb/gadget/f_acm.c | 24 +
drivers/usb/gadget/f_adb.c | 45 +
drivers/usb/gadget/f_ecm.c | 116 +-
drivers/usb/gadget/f_eem.c | 72 +-
drivers/usb/gadget/f_mass_storage.c | 514 +-
drivers/usb/gadget/f_mtp.c | 91 +-
drivers/usb/gadget/f_ncm.c | 74 +-
drivers/usb/gadget/f_rndis.c | 129 +-
drivers/usb/gadget/f_subset.c | 76 +-
drivers/usb/gadget/gadget_chips.h | 16 +
drivers/usb/gadget/rndis.c | 11 -
drivers/usb/gadget/storage_common.c | 120 +-
drivers/usb/gadget/u_ether.c | 64 +-
drivers/usb/gadget/u_serial.c | 3 +-
drivers/usb/host/Kconfig | 49 +-
drivers/usb/host/Makefile | 5 +-
drivers/usb/host/ehci-hcd.c | 45 +
drivers/usb/host/ehci-hub.c | 404 +-
drivers/usb/host/ehci-q.c | 33 +-
drivers/usb/host/ehci-s5p.c | 638 ++-
drivers/usb/host/ehci.h | 25 +-
drivers/usb/host/ohci-hcd.c | 10 +-
drivers/usb/host/xhci-mem.c | 38 +-
drivers/usb/host/xhci-pci.c | 96 +-
drivers/usb/host/xhci-ring.c | 7 +-
drivers/usb/host/xhci.c | 241 +-
drivers/usb/host/xhci.h | 8 +
drivers/usb/misc/Kconfig | 42 +
drivers/usb/misc/Makefile | 6 +
drivers/usb/serial/Kconfig | 9 +
drivers/usb/serial/Makefile | 1 +
drivers/usb/serial/qcserial.c | 44 +-
drivers/usb/serial/usb-serial.c | 7 +-
drivers/usb/serial/usb-wwan.h | 12 +-
drivers/usb/serial/usb_wwan.c | 91 +-
drivers/usb/storage/usb.c | 3 +
drivers/video/Kconfig | 56 +-
drivers/video/Makefile | 21 +
drivers/video/backlight/Kconfig | 97 +
drivers/video/backlight/Makefile | 10 +
drivers/video/backlight/backlight.c | 48 +-
drivers/video/backlight/lcd.c | 22 +
drivers/video/backlight/pwm_bl.c | 8 +
drivers/video/fbmem.c | 21 +-
drivers/video/s3c-fb.c | 1773 ++++++-
drivers/watchdog/s3c2410_wdt.c | 35 +-
firmware/Makefile | 91 +-
fs/bio.c | 4 +
fs/buffer.c | 46 +
fs/drop_caches.c | 16 +
fs/ecryptfs/Kconfig | 7 +
fs/ecryptfs/ecryptfs_kernel.h | 26 +
fs/ecryptfs/file.c | 149 +
fs/ecryptfs/inode.c | 33 +
fs/ecryptfs/keystore.c | 6 +-
fs/ecryptfs/main.c | 76 +
fs/ecryptfs/miscdev.c | 2 +-
fs/ecryptfs/super.c | 4 +
fs/ext4/extents.c | 8 +-
fs/ext4/ialloc.c | 3 +-
fs/ext4/inode.c | 4 +
fs/ext4/namei.c | 10 +-
fs/ext4/super.c | 3 +
fs/fat/dir.c | 4 +-
fs/fat/file.c | 59 +
fs/fat/inode.c | 65 +
fs/fuse/dev.c | 63 +-
fs/fuse/fuse_i.h | 11 +-
fs/fuse/inode.c | 18 +-
fs/jbd2/checkpoint.c | 3 +-
fs/jbd2/transaction.c | 21 +
fs/proc/array.c | 4 +
fs/proc/base.c | 32 +
include/asm-generic/emergency-restart.h | 4 +
include/asm-generic/vmlinux.lds.h | 2 +
include/crypto/aead.h | 21 +-
include/crypto/algapi.h | 1 +
include/crypto/compress.h | 40 +
include/crypto/hash.h | 34 +-
include/crypto/rng.h | 5 +
include/crypto/skcipher.h | 18 +-
include/drm/Kbuild | 2 +
include/drm/drm.h | 22 +-
include/drm/drmP.h | 130 +-
include/drm/drm_crtc.h | 324 +-
include/drm/drm_crtc_helper.h | 5 +-
include/drm/drm_dp_helper.h | 61 +
include/drm/drm_edid.h | 10 +
include/drm/drm_fb_helper.h | 2 -
include/drm/drm_mode.h | 82 +
include/drm/i915_drm.h | 41 +
include/drm/intel-gtt.h | 6 +
include/drm/radeon_drm.h | 65 +-
include/drm/sis_drm.h | 4 +
include/drm/ttm/ttm_bo_api.h | 27 +-
include/drm/ttm/ttm_bo_driver.h | 209 +-
include/drm/ttm/ttm_lock.h | 2 +-
include/drm/ttm/ttm_memory.h | 2 +-
include/drm/ttm/ttm_object.h | 4 +-
include/drm/ttm/ttm_page_alloc.h | 77 +-
include/drm/via_drm.h | 4 +
include/drm/vmwgfx_drm.h | 367 +-
include/linux/android_alarm.h | 14 +-
include/linux/backlight.h | 10 +
include/linux/bitmap.h | 24 +-
include/linux/clocksource.h | 1 +
include/linux/compaction.h | 2 +
include/linux/cpufreq.h | 17 +
include/linux/crypto.h | 121 +-
include/linux/device.h | 7 +
include/linux/earlysuspend.h | 1 -
include/linux/fb.h | 4 +
include/linux/ftrace.h | 8 +-
include/linux/ftrace_event.h | 2 +
include/linux/genalloc.h | 50 +-
include/linux/genhd.h | 7 +
include/linux/gfp.h | 30 +
include/linux/gpio_keys.h | 4 +
include/linux/highmem.h | 15 +
include/linux/hwmon.h | 34 +
include/linux/ieee80211.h | 10 +
include/linux/if_arp.h | 1 +
include/linux/init.h | 4 +
include/linux/input.h | 26 +-
include/linux/iommu.h | 142 +-
include/linux/ion.h | 75 +
include/linux/irq.h | 1 +
include/linux/lcd.h | 15 +
include/linux/leds-lp5521.h | 25 +
include/linux/leds.h | 6 +
include/linux/mfd/max8997-private.h | 664 +--
include/linux/mfd/max8997.h | 244 +-
include/linux/mfd/wm8994/core.h | 8 +
include/linux/mfd/wm8994/pdata.h | 46 +-
include/linux/mfd/wm8994/registers.h | 218 +
include/linux/migrate.h | 12 +
include/linux/mm.h | 45 +-
include/linux/mm_types.h | 15 +
include/linux/mmc/card.h | 34 +-
include/linux/mmc/core.h | 21 +-
include/linux/mmc/dw_mmc.h | 60 +-
include/linux/mmc/host.h | 103 +-
include/linux/mmc/mmc.h | 117 +-
include/linux/mmc/pm.h | 3 +
include/linux/mmc/sdhci.h | 1 +
include/linux/mmc/sdio.h | 31 +-
include/linux/mmc/sdio_func.h | 1 -
include/linux/mmzone.h | 44 +
include/linux/mod_devicetable.h | 2 +-
include/linux/msdos_fs.h | 1 +
include/linux/nl80211.h | 4 +-
include/linux/opp.h | 12 +
include/linux/page-flags.h | 50 +
include/linux/page-isolation.h | 34 +
include/linux/pm_qos_params.h | 9 +-
include/linux/power/max17042_battery.h | 2 +
include/linux/power_supply.h | 54 +
include/linux/rbtree.h | 11 +
include/linux/rtc.h | 20 +-
include/linux/sched.h | 2 +
include/linux/skbuff.h | 10 +-
include/linux/suspend.h | 8 +
include/linux/thermal.h | 1 +
include/linux/tty.h | 6 +-
include/linux/usb.h | 4 +
include/linux/usb/ch11.h | 38 +
include/linux/usb/ch9.h | 2 +
include/linux/usb/composite.h | 64 +-
include/linux/usb/ehci_def.h | 6 +
include/linux/usb/f_accessory.h | 65 +-
include/linux/usb/gadget.h | 32 +
include/linux/usb/quirks.h | 9 +
include/linux/usb/usbnet.h | 3 +-
include/linux/v4l2-mediabus.h | 2 +
include/linux/videodev2.h | 471 +-
include/linux/vmalloc.h | 4 +
include/linux/wakelock.h | 1 -
include/linux/workqueue.h | 4 +
include/media/m5mols.h | 20 +-
include/media/s5p_fimc.h | 28 +-
include/media/v4l2-fh.h | 2 +
include/media/v4l2-mem2mem.h | 3 +
include/media/v4l2-subdev.h | 12 +
include/media/videobuf2-core.h | 50 +
include/net/bluetooth/bluetooth.h | 8 +-
include/net/bluetooth/hci.h | 22 +-
include/net/bluetooth/hci_core.h | 18 +-
include/net/bluetooth/l2cap.h | 8 +-
include/net/bluetooth/mgmt.h | 14 +
include/net/bluetooth/rfcomm.h | 6 +-
include/net/bluetooth/sco.h | 6 +
include/net/bluetooth/smp.h | 8 +-
include/net/cfg80211.h | 26 +
include/scsi/scsi_host.h | 3 +
include/sound/asound.h | 3 +-
include/sound/soc-dapm.h | 2 +-
include/sound/soc.h | 12 +-
include/trace/events/cpufreq_interactive.h | 16 +-
init/Kconfig | 5 +
init/main.c | 4 +-
kernel/hrtimer.c | 3 +
kernel/irq/generic-chip.c | 16 +
kernel/irq/handle.c | 4 +
kernel/module.c | 6 +-
kernel/notifier.c | 5 +-
kernel/pm_qos_params.c | 59 +-
kernel/power/Kconfig | 37 +
kernel/power/earlysuspend.c | 50 +-
kernel/power/hibernate.c | 66 +-
kernel/power/main.c | 361 +-
kernel/power/power.h | 19 +
kernel/power/snapshot.c | 83 +
kernel/power/suspend.c | 75 +-
kernel/power/swap.c | 29 +-
kernel/power/wakelock.c | 29 +-
kernel/printk.c | 83 +-
kernel/sched.c | 24 +-
kernel/sched_clock.c | 12 -
kernel/sched_debug.c | 9 +-
kernel/softirq.c | 7 +
kernel/sys.c | 8 +-
kernel/time/Kconfig | 4 +
kernel/time/timekeeping.c | 125 +
kernel/workqueue.c | 155 +
lib/Kconfig.debug | 17 +
lib/bitmap.c | 22 +-
lib/genalloc.c | 190 +-
lib/klist.c | 2 +-
lib/list_debug.c | 33 +-
lib/ts_fsm.c | 2 +-
mm/Kconfig | 65 +-
mm/Makefile | 33 +-
mm/ashmem.c | 3 +-
mm/compaction.c | 4 +
mm/filemap_xip.c | 4 +
mm/fremap.c | 4 +
mm/internal.h | 35 +
mm/memory-failure.c | 9 +
mm/memory.c | 76 +-
mm/memory_hotplug.c | 17 +
mm/mempolicy.c | 11 +
mm/oom_kill.c | 4 +
mm/page_alloc.c | 95 +-
mm/rmap.c | 21 +
mm/shmem.c | 9 +
mm/slub.c | 10 +
mm/swap.c | 15 +
mm/swapfile.c | 159 +-
mm/truncate.c | 6 +
mm/vmalloc.c | 16 +
mm/vmscan.c | 105 +-
mm/vmstat.c | 10 +
net/Kconfig | 2 +
net/Makefile | 14 +-
net/bluetooth/hci_conn.c | 29 +
net/bluetooth/hci_event.c | 22 +-
net/bluetooth/l2cap_core.c | 117 +
net/bluetooth/rfcomm/core.c | 21 +-
net/bluetooth/sco.c | 5 +
net/core/skbuff.c | 10 +-
net/ipv4/tcp.c | 4 +-
net/ipv4/tcp_output.c | 11 +-
net/ipv6/addrconf.c | 11 +
net/ipv6/route.c | 4 +-
net/netfilter/nf_conntrack_core.c | 9 +
net/netfilter/xt_qtaguid.c | 12 +-
net/phonet/af_phonet.c | 2 +
net/phonet/socket.c | 2 +-
net/phonet/sysctl.c | 2 +-
net/wireless/core.h | 6 +-
net/wireless/nl80211.c | 23 +-
net/wireless/scan.c | 3 +
net/wireless/sme.c | 60 +-
net/wireless/util.c | 6 +-
net/xfrm/xfrm_policy.c | 10 +-
scripts/checkpatch.pl | 684 ++-
scripts/kconfig/.gitignore | 24 +-
security/commoncap.c | 2 +
security/security.c | 1 +
security/smack/smack.h | 84 +-
security/smack/smack_access.c | 346 +-
security/smack/smack_lsm.c | 480 +-
security/smack/smackfs.c | 1339 +++--
sound/core/control.c | 2 +
sound/core/pcm_native.c | 6 +-
sound/soc/codecs/Kconfig | 3 +
sound/soc/codecs/Makefile | 1 +
sound/soc/codecs/wm8993.c | 102 +-
sound/soc/codecs/wm8993.h | 9 +
sound/soc/codecs/wm8994-tables.c | 24 +-
sound/soc/codecs/wm8994.c | 1700 +++++--
sound/soc/codecs/wm8994.h | 21 +
sound/soc/codecs/wm_hubs.c | 472 +-
sound/soc/codecs/wm_hubs.h | 35 +-
sound/soc/samsung/Kconfig | 166 +-
sound/soc/samsung/Makefile | 34 +
sound/soc/samsung/ac97.c | 2 +-
sound/soc/samsung/dma.c | 78 +-
sound/soc/samsung/dma.h | 3 +
sound/soc/samsung/i2s.c | 508 +-
sound/soc/samsung/i2s.h | 118 +-
sound/soc/samsung/pcm.c | 101 +-
sound/soc/samsung/regs-i2s-v2.h | 11 +-
sound/soc/samsung/s3c-i2s-v2.c | 2 +-
sound/soc/samsung/s3c2412-i2s.c | 10 +-
sound/soc/samsung/s3c24xx-i2s.c | 4 +-
sound/soc/samsung/smdk_spdif.c | 33 +-
sound/soc/samsung/smdk_wm8994.c | 172 +-
sound/soc/samsung/spdif.c | 4 +-
sound/soc/soc-core.c | 63 +-
sound/soc/soc-dapm.c | 102 +-
sound/soc/soc-jack.c | 43 +
sound/soc/soc-utils.c | 103 +
usr/.gitignore | 14 +
1145 files changed, 99163 insertions(+), 44179 deletions(-)
diff --git aosp-v3.0/Makefile smdk4210/Makefile
index ac9701b..d6fe849 100644
--- aosp-v3.0/Makefile
+++ smdk4210/Makefile
@@ -192,8 +192,8 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
export KBUILD_BUILDHOST := $(SUBARCH)
-ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH ?= arm
+CROSS_COMPILE ?= ../../../prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
# Architecture as present in compile.h
UTS_MACHINE := $(ARCH)
@@ -368,7 +368,8 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration \
-Wno-format-security \
- -fno-delete-null-pointer-checks
+ -fno-delete-null-pointer-checks \
+ -mtune=cortex-a9
KBUILD_AFLAGS_KERNEL :=
KBUILD_CFLAGS_KERNEL :=
KBUILD_AFLAGS := -D__ASSEMBLY__
@@ -564,6 +565,14 @@ else
KBUILD_CFLAGS += -O2
endif
+ifdef CONFIG_CC_CHECK_WARNING_STRICTLY
+KBUILD_CFLAGS += -fdiagnostics-show-option -Werror \
+ -Wno-error=unused-function \
+ -Wno-error=unused-variable \
+ -Wno-error=unused-value \
+ -Wno-error=unused-label
+endif
+
include $(srctree)/arch/$(SRCARCH)/Makefile
ifneq ($(CONFIG_FRAME_WARN),0)
diff --git aosp-v3.0/arch/Kconfig smdk4210/arch/Kconfig
index 26b0e23..b6ac1e9 100644
--- aosp-v3.0/arch/Kconfig
+++ smdk4210/arch/Kconfig
@@ -127,6 +127,9 @@ config HAVE_DMA_ATTRS
config USE_GENERIC_SMP_HELPERS
bool
+config HAVE_DMA_CONTIGUOUS
+ bool
+
config HAVE_REGS_AND_STACK_ACCESS_API
bool
help
diff --git aosp-v3.0/arch/alpha/include/asm/futex.h smdk4210/arch/alpha/include/asm/futex.h
index f939794..e8a761a 100644
--- aosp-v3.0/arch/alpha/include/asm/futex.h
+++ smdk4210/arch/alpha/include/asm/futex.h
@@ -108,7 +108,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" lda $31,3b-2b(%0)\n"
" .previous\n"
: "+r"(ret), "=&r"(prev), "=&r"(cmp)
- : "r"(uaddr), "r"((long)(int)oldval), "r"(newval)
+ : "r"(uaddr), "r"((long)oldval), "r"(newval)
: "memory");
*uval = prev;
diff --git aosp-v3.0/arch/arm/Kconfig smdk4210/arch/arm/Kconfig
index d8e2570..b2e01fe 100644
--- aosp-v3.0/arch/arm/Kconfig
+++ smdk4210/arch/arm/Kconfig
@@ -4,6 +4,7 @@ config ARM
select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE
+ select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
@@ -37,6 +38,9 @@ config ARM
Europe. There is an ARM Linux project with a web page at
<http://www.arm.linux.org.uk/>.
+config ARM_HAS_SG_CHAIN
+ bool
+
config HAVE_PWM
bool
@@ -110,7 +114,6 @@ config STACKTRACE_SUPPORT
config HAVE_LATENCYTOP_SUPPORT
bool
- depends on !SMP
default y
config LOCKDEP_SUPPORT
@@ -213,6 +216,9 @@ config ARM_PATCH_PHYS_VIRT_16BIT
to allow physical memory down to a theoretical minimum of 64K
boundaries.
+config ARCH_HIBERNATION_POSSIBLE
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -761,19 +767,22 @@ config ARCH_S5PV210
help
Samsung S5PV210/S5PC110 series based systems
-config ARCH_EXYNOS4
- bool "Samsung EXYNOS4"
+config ARCH_EXYNOS
+ bool "Samsung EXYNOS"
select CPU_V7
- select ARCH_SPARSEMEM_ENABLE
+ select ARCH_FLATMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
+ select CLKDEV_LOOKUP
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
help
- Samsung EXYNOS4 series based systems
+ Samsung EXYNOS series based systems
config ARCH_SHARK
bool "Shark"
@@ -987,7 +996,7 @@ source "arch/arm/mach-s5pc100/Kconfig"
source "arch/arm/mach-s5pv210/Kconfig"
-source "arch/arm/mach-exynos4/Kconfig"
+source "arch/arm/mach-exynos/Kconfig"
source "arch/arm/mach-shmobile/Kconfig"
@@ -1033,6 +1042,11 @@ config ARM_TIMER_SP804
source arch/arm/mm/Kconfig
+config ARM_PLD_SIZE
+ int
+ default 64 if ARCH_EXYNOS5
+ default 32
+
config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
@@ -1163,6 +1177,16 @@ config ARM_ERRATA_720789
tables. The workaround changes the TLB flushing routines to invalidate
entries regardless of the ASID.
+config ARM_ERRATA_720791
+ bool "ARM errata: Dynamic high-level clock gating corrupts the Jazelle instruction stream"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 720791 Cortex-A9
+ (r1p0..r1p2) erratum. The Jazelle instruction stream may be
+ corrupted when dynamic high-level clock gating is enabled.
+ This workaround disables gating the Core clock when the Instruction
+ side is waiting for a Page Table Walk answer or linefill completion.
+
config PL310_ERRATA_727915
bool "Background Clean & Invalidate by Way operation can cause data corruption"
depends on CACHE_L2X0
@@ -1234,6 +1258,29 @@ config ARM_ERRATA_754327
This workaround defines cpu_relax() as smp_mb(), preventing correctly
written polling loops from denying visibility of updates to memory.
+config ARM_ERRATA_761320
+ bool "ARM errata: no direct eviction"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 761320 Cortex-A9 erratum.
+
+config ARM_ERRATA_761171
+ bool "ARM errata: disable store streaming of mode 3"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 761171 Cortex-A15 erratum.
+
+config ARM_ERRATA_762974
+ bool "ARM errata: disable l2 prefetch"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 762964 Cortex-A15 erratum.
+
+config ARM_ERRATA_763722
+ bool "ARM errata: disable store streaming of mode 2 and mode 3"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 763722 Cortex-A15 erratum.
endmenu
source "arch/arm/common/Kconfig"
@@ -1336,7 +1383,7 @@ config SMP
depends on GENERIC_CLOCKEVENTS
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
- ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
+ ARCH_EXYNOS || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
@@ -1423,7 +1470,7 @@ config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP
default y
- select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
+ select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS_MCT)
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
@@ -1435,7 +1482,8 @@ source kernel/Kconfig.preempt
config HZ
int
default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
- ARCH_S5PV210 || ARCH_EXYNOS4
+ ARCH_S5PV210 || (ARCH_EXYNOS && !MACH_FPGA5410)
+ default 20 if MACH_FPGA5410
default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
default AT91_TIMER_HZ if ARCH_AT91
default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
@@ -1534,6 +1582,16 @@ config ARCH_SELECT_MEMORY_MODEL
config HAVE_ARCH_PFN_VALID
def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
+config ARCH_SKIP_SECONDARY_CALIBRATE
+ bool "Skip secondary CPU calibration"
+ depends on SMP
+ help
+ On some architectures, secondary cores shares clock with primiary
+ core and hence scale together. Hence secondary core lpj calibration
+ is not necessary and can be skipped to save considerable time.
+
+ If unsure, say n.
+
config HIGHMEM
bool "High Memory Support"
depends on MMU
@@ -1706,6 +1764,8 @@ config ARM_FLUSH_CONSOLE_ON_RESTART
released if it failed to be acquired, which will cause all the
pending messages to be flushed.
+source "arch/arm/mvp/Kconfig"
+
endmenu
menu "Boot options"
diff --git aosp-v3.0/arch/arm/Kconfig.debug smdk4210/arch/arm/Kconfig.debug
index 81cbe40..25846f8 100644
--- aosp-v3.0/arch/arm/Kconfig.debug
+++ smdk4210/arch/arm/Kconfig.debug
@@ -129,4 +129,9 @@ config DEBUG_S3C_UART
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
+config CACHE_PERF
+ tristate "cache performance test"
+ help
+ Measure the performance of cache maintenance operation.
+
endmenu
diff --git aosp-v3.0/arch/arm/Makefile smdk4210/arch/arm/Makefile
index f5b2b39..825ad6d 100644
--- aosp-v3.0/arch/arm/Makefile
+++ smdk4210/arch/arm/Makefile
@@ -178,7 +178,7 @@ machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
machine-$(CONFIG_ARCH_S5PC100) := s5pc100
machine-$(CONFIG_ARCH_S5PV210) := s5pv210
-machine-$(CONFIG_ARCH_EXYNOS4) := exynos4
+machine-$(CONFIG_ARCH_EXYNOS) := exynos
machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
@@ -249,6 +249,7 @@ endif
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
+core-$(CONFIG_VMWARE_MVP) += arch/arm/mvp/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
diff --git aosp-v3.0/arch/arm/boot/Makefile smdk4210/arch/arm/boot/Makefile
index 9128fdd..9ec1a8d 100644
--- aosp-v3.0/arch/arm/boot/Makefile
+++ smdk4210/arch/arm/boot/Makefile
@@ -12,6 +12,7 @@
#
MKIMAGE := $(srctree)/scripts/mkuboot.sh
+MKFIPS := $(srctree)/scripts/mk_fipsbinary.sh
ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
@@ -55,6 +56,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
+ifeq ($(CONFIG_CRYPTO_FIPS),y)
+ $(MKFIPS) $(obj)/zImage
+endif
@echo ' Kernel: $@ is ready'
endif
diff --git aosp-v3.0/arch/arm/boot/compressed/Makefile smdk4210/arch/arm/boot/compressed/Makefile
index 23aad07..54c9428 100644
--- aosp-v3.0/arch/arm/boot/compressed/Makefile
+++ smdk4210/arch/arm/boot/compressed/Makefile
@@ -16,6 +16,11 @@ endif
endif
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+# change@wtl.rsengott
+# FIPS_KERNEL_RAM_BASE is start of kernel text in RAM
+ifeq ($(CONFIG_CRYPTO_FIPS),y)
+AFLAGS_head.o += -DFIPS_KERNEL_RAM_BASE=0x40008000
+endif
HEAD = head.o
OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
diff --git aosp-v3.0/arch/arm/boot/compressed/head.S smdk4210/arch/arm/boot/compressed/head.S
index e58603b..3a959994 100644
--- aosp-v3.0/arch/arm/boot/compressed/head.S
+++ smdk4210/arch/arm/boot/compressed/head.S
@@ -186,7 +186,7 @@ restart: adr r0, LC0
* We might be running at a different address. We need
* to fix up various pointers.
*/
- sub r0, r0, r1 @ calculate the delta offset
+ sub r0, r0, r1 @ calculate the delta offset
add r6, r6, r0 @ _edata
add r10, r10, r0 @ inflated kernel size location
@@ -292,7 +292,13 @@ wont_overwrite:
* sp = stack pointer
*/
teq r0, #0
+#ifndef CONFIG_CRYPTO_FIPS
beq not_relocated
+#else
+ movw r5, #:lower16:zimage_ram_base_addr
+ movt r5, #:upper16:zimage_ram_base_addr
+ beq not_relocated_copy
+#endif
add r11, r11, r0
add r12, r12, r0
@@ -305,6 +311,11 @@ wont_overwrite:
add r2, r2, r0
add r3, r3, r0
+#ifdef CONFIG_CRYPTO_FIPS
+ movw r5, #:lower16:zimage_ram_base_addr
+ movt r5, #:upper16:zimage_ram_base_addr
+ bl copy_compressed
+#endif
/*
* Relocate all entries in the GOT table.
*/
@@ -367,6 +378,10 @@ LC0: .word LC0 @ r1
.word .L_user_stack_end @ sp
.size LC0, . - LC0
+#ifdef CONFIG_CRYPTO_FIPS
+ .equ zimage_ram_base_addr, FIPS_KERNEL_RAM_BASE
+#endif
+
#ifdef CONFIG_ARCH_RPC
.globl params
params: ldr r0, =0x10000100 @ params_phys for RPC
@@ -375,6 +390,29 @@ params: ldr r0, =0x10000100 @ params_phys for RPC
.align
#endif
+
+#ifdef CONFIG_CRYPTO_FIPS
+not_relocated_copy:
+ bl copy_compressed
+ b not_relocated
+
+copy_compressed:
+ mov r1, r5
+ add r9, r4, #CONFIG_CRYPTO_FIPS_INTEG_OFFSET
+
+1:
+ ldmia r1!, {r5}
+ stmia r9!, {r5}
+ cmp r1, r2
+ blo 1b
+
+ .rept 8
+ ldmia r1!, {r5}
+ stmia r9!, {r5}
+ .endr
+ mov pc, lr
+#endif
+
/*
* Turn on the cache. We need to setup some page tables so that we
* can have both the I and D caches on.
diff --git aosp-v3.0/arch/arm/common/gic.c smdk4210/arch/arm/common/gic.c
index 4ddd0a6..7d3e611 100644
--- aosp-v3.0/arch/arm/common/gic.c
+++ smdk4210/arch/arm/common/gic.c
@@ -33,17 +33,25 @@
#include <asm/mach/irq.h>
#include <asm/hardware/gic.h>
+struct gic_chip_data {
+ unsigned int irq_offset;
+ void __percpu __iomem **dist_base;
+ void __percpu __iomem **cpu_base;
+#ifdef CONFIG_CPU_PM
+ u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+ u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+ u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+ u32 __percpu *saved_ppi_enable;
+ u32 __percpu *saved_ppi_conf;
+#endif
+ unsigned int gic_irqs;
+};
+
static DEFINE_SPINLOCK(irq_controller_lock);
/* Address of GIC 0 CPU interface */
void __iomem *gic_cpu_base_addr __read_mostly;
-struct gic_chip_data {
- unsigned int irq_offset;
- void __iomem *dist_base;
- void __iomem *cpu_base;
-};
-
/*
* Supported arch specific GIC irq extension.
* Default make them NULL.
@@ -63,16 +71,26 @@ struct irq_chip gic_arch_extn = {
static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
+static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data)
+{
+ return *__this_cpu_ptr(data->dist_base);
+}
+
static inline void __iomem *gic_dist_base(struct irq_data *d)
{
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
- return gic_data->dist_base;
+ return gic_data_dist_base(gic_data);
+}
+
+static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data)
+{
+ return *__this_cpu_ptr(data->cpu_base);
}
static inline void __iomem *gic_cpu_base(struct irq_data *d)
{
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
- return gic_data->cpu_base;
+ return gic_data_cpu_base(gic_data);
}
static inline unsigned int gic_irq(struct irq_data *d)
@@ -223,7 +241,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
spin_lock(&irq_controller_lock);
- status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
+ status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
spin_unlock(&irq_controller_lock);
gic_irq = (status & 0x3ff);
@@ -266,7 +284,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
- void __iomem *base = gic->dist_base;
+ void __iomem *base = gic_data_dist_base(gic);
u32 cpumask = 1 << smp_processor_id();
cpumask |= cpumask << 8;
@@ -329,8 +347,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
- void __iomem *dist_base = gic->dist_base;
- void __iomem *base = gic->cpu_base;
+ void __iomem *dist_base = gic_data_dist_base(gic);
+ void __iomem *base = gic_data_cpu_base(gic);
int i;
/*
@@ -354,12 +372,24 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
struct gic_chip_data *gic;
+ int cpu;
BUG_ON(gic_nr >= MAX_GIC_NR);
gic = &gic_data[gic_nr];
- gic->dist_base = dist_base;
- gic->cpu_base = cpu_base;
+ gic->dist_base = alloc_percpu(void __iomem *);
+ gic->cpu_base = alloc_percpu(void __iomem *);
+ if (WARN_ON(!gic->dist_base || !gic->cpu_base)) {
+ free_percpu(gic->dist_base);
+ free_percpu(gic->cpu_base);
+ return;
+ }
+
+ for_each_possible_cpu(cpu) {
+ *per_cpu_ptr(gic->dist_base, cpu) = dist_base;
+ *per_cpu_ptr(gic->cpu_base, cpu) = cpu_base;
+ }
+
gic->irq_offset = (irq_start - 1) & ~31;
if (gic_nr == 0)
@@ -369,10 +399,16 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
gic_cpu_init(gic);
}
-void __cpuinit gic_secondary_init(unsigned int gic_nr)
+void __cpuinit gic_secondary_init_base(unsigned int gic_nr,
+ void __iomem *dist_base,
+ void __iomem *cpu_base)
{
BUG_ON(gic_nr >= MAX_GIC_NR);
+ if (dist_base)
+ *__this_cpu_ptr(gic_data[gic_nr].dist_base) = dist_base;
+ if (cpu_base)
+ *__this_cpu_ptr(gic_data[gic_nr].cpu_base) = cpu_base;
gic_cpu_init(&gic_data[gic_nr]);
}
@@ -398,6 +434,6 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
dsb();
/* this always happens on GIC0 */
- writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
+ writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
}
#endif
diff --git aosp-v3.0/arch/arm/common/pl330.c smdk4210/arch/arm/common/pl330.c
index 97912fa..6147b24 100644
--- aosp-v3.0/arch/arm/common/pl330.c
+++ smdk4210/arch/arm/common/pl330.c
@@ -1116,6 +1116,54 @@ static inline int _loop(unsigned dry_run, u8 buf[],
return off;
}
+/* Returns bytes consumed and updates bursts */
+static inline int _loop_infiniteloop(unsigned dry_run, u8 buf[],
+ unsigned long bursts, const struct _xfer_spec *pxs, int ev)
+{
+ int cyc, off;
+ unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe;
+ struct _arg_LPEND lpend;
+
+ off = 0;
+ ljmpfe = off;
+ lcnt0 = pxs->r->infiniteloop;
+ lcnt1 = 256;
+ cyc = bursts/256;
+
+ /* forever loop */
+ off += _emit_MOV(dry_run, &buf[off], SAR, pxs->x->src_addr);
+ off += _emit_MOV(dry_run, &buf[off], DAR, pxs->x->dst_addr);
+
+ /* loop0 */
+ off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
+ ljmp0 = off;
+
+ /* loop1 */
+ off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
+ ljmp1 = off;
+ off += _bursts(dry_run, &buf[off], pxs, cyc);
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 1;
+ lpend.bjump = off - ljmp1;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+ off += _emit_SEV(dry_run, &buf[off], ev);
+
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 0;
+ lpend.bjump = off - ljmp0;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+ lpend.cond = ALWAYS;
+ lpend.forever = true;
+ lpend.loop = 1;
+ lpend.bjump = off - ljmpfe;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+ return off;
+}
+
static inline int _setup_loops(unsigned dry_run, u8 buf[],
const struct _xfer_spec *pxs)
{
@@ -1150,6 +1198,20 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
return off;
}
+static inline int _setup_xfer_infiniteloop(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int ev)
+{
+ struct pl330_xfer *x = pxs->x;
+ u32 ccr = pxs->ccr;
+ unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr);
+ int off = 0;
+
+ /* Setup Loop(s) */
+ off += _loop_infiniteloop(dry_run, &buf[off], bursts, pxs, ev);
+
+ return off;
+}
+
/*
* A req is a sequence of one or more xfer units.
* Returns the number of bytes taken to setup the MC for the req.
@@ -1168,22 +1230,33 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
x = pxs->r->x;
- do {
+
+ if (!pxs->r->infiniteloop) {
+ do {
+ /* Error if xfer length is not aligned at burst size */
+ if (x->bytes % (BRST_SIZE(pxs->ccr)
+ * BRST_LEN(pxs->ccr)))
+ return -EINVAL;
+
+ pxs->x = x;
+ off += _setup_xfer(dry_run, &buf[off], pxs);
+
+ x = x->next;
+ } while (x);
+
+ /* DMASEV peripheral/event */
+ off += _emit_SEV(dry_run, &buf[off], thrd->ev);
+ /* DMAEND */
+ off += _emit_END(dry_run, &buf[off]);
+ } else {
/* Error if xfer length is not aligned at burst size */
if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
return -EINVAL;
pxs->x = x;
- off += _setup_xfer(dry_run, &buf[off], pxs);
-
- x = x->next;
- } while (x);
-
- /* DMASEV peripheral/event */
- off += _emit_SEV(dry_run, &buf[off], thrd->ev);
- /* DMAEND */
- off += _emit_END(dry_run, &buf[off]);
-
+ off += _setup_xfer_infiniteloop
+ (dry_run, &buf[off], pxs, thrd->ev);
+ }
return off;
}
@@ -1281,17 +1354,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)) {
@@ -1459,6 +1532,9 @@ int pl330_update(const struct pl330_info *pi)
id = pl330->events[ev];
+ if (id == -1) /* Released? */
+ continue;
+
thrd = &pl330->channels[id];
active = _thrd_active(thrd);
@@ -1468,10 +1544,13 @@ int pl330_update(const struct pl330_info *pi)
active -= 1;
rqdone = &thrd->req[active];
- MARK_FREE(rqdone);
- /* Get going again ASAP */
- _start(thrd);
+ if (!rqdone->r->infiniteloop) {
+ MARK_FREE(rqdone);
+
+ /* Get going again ASAP */
+ _start(thrd);
+ }
/* For now, just make a list of callbacks to be done */
list_add_tail(&rqdone->rqd, &pl330->req_done);
diff --git aosp-v3.0/arch/arm/include/asm/assembler.h smdk4210/arch/arm/include/asm/assembler.h
index 4e25f18..7bb8bf9 100644
--- aosp-v3.0/arch/arm/include/asm/assembler.h
+++ smdk4210/arch/arm/include/asm/assembler.h
@@ -298,4 +298,13 @@
.macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
+
+/* Utility macro for declaring string literals */
+ .macro string name:req, string
+ .type \name , #object
+\name:
+ .asciz "\string"
+ .size \name , . - \name
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git aosp-v3.0/arch/arm/include/asm/bitops.h smdk4210/arch/arm/include/asm/bitops.h
index b4892a0..f428059 100644
--- aosp-v3.0/arch/arm/include/asm/bitops.h
+++ smdk4210/arch/arm/include/asm/bitops.h
@@ -26,8 +26,8 @@
#include <linux/compiler.h>
#include <asm/system.h>
-#define smp_mb__before_clear_bit() mb()
-#define smp_mb__after_clear_bit() mb()
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
/*
* These functions are the basis of our bit ops.
diff --git aosp-v3.0/arch/arm/include/asm/cacheflush.h smdk4210/arch/arm/include/asm/cacheflush.h
index 1252a26..ce110c3 100644
--- aosp-v3.0/arch/arm/include/asm/cacheflush.h
+++ smdk4210/arch/arm/include/asm/cacheflush.h
@@ -16,6 +16,7 @@
#include <asm/shmparam.h>
#include <asm/cachetype.h>
#include <asm/outercache.h>
+#include <mach/smc.h>
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -206,6 +207,12 @@ static inline void __flush_icache_all(void)
#define flush_cache_all() __cpuc_flush_kern_all()
+#ifndef CONFIG_SMP
+#define flush_all_cpu_caches() flush_cache_all()
+#else
+extern void flush_all_cpu_caches(void);
+#endif
+
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
@@ -344,4 +351,37 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
flush_cache_all();
}
+/*
+ * Control the full line of zero function that must be enabled
+ * only when the slaves connected on cortex-A9 AXI master port support it.
+ * The L2-310 cache controller supports this feature.
+ */
+#ifdef CONFIG_CACHE_L2X0
+static inline void __enable_cache_foz(int enable)
+{
+ int val;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 1\n"
+ : "=r" (val));
+
+ /* enable/disable Foz */
+ if (enable)
+ val |= ((1<<3));
+ else
+ val &= (~(1<<3));
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_CP15(1, 0, 0, 1), val, 0);
+#else
+ asm volatile("mcr p15, 0, %0, c1, c0, 1" : : "r" (val));
+#endif
+}
+
+#define enable_cache_foz() __enable_cache_foz(1)
+#define disable_cache_foz() __enable_cache_foz(0)
+#else
+#define enable_cache_foz() do { } while (0)
+#define disable_cache_foz() do { } while (0)
+#endif
#endif
diff --git aosp-v3.0/arch/arm/include/asm/device.h smdk4210/arch/arm/include/asm/device.h
index 9f390ce..6615f03 100644
--- aosp-v3.0/arch/arm/include/asm/device.h
+++ smdk4210/arch/arm/include/asm/device.h
@@ -10,6 +10,9 @@ struct dev_archdata {
#ifdef CONFIG_DMABOUNCE
struct dmabounce_device_info *dmabounce;
#endif
+#ifdef CONFIG_IOMMU_API
+ void *iommu; /* private IOMMU data */
+#endif
};
struct pdev_archdata {
diff --git aosp-v3.0/arch/arm/include/asm/dma-mapping.h smdk4210/arch/arm/include/asm/dma-mapping.h
index 4fff837..9ce57c9 100644
--- aosp-v3.0/arch/arm/include/asm/dma-mapping.h
+++ smdk4210/arch/arm/include/asm/dma-mapping.h
@@ -9,6 +9,9 @@
#include <asm-generic/dma-coherent.h>
#include <asm/memory.h>
+#ifdef CONFIG_DMA_CMA
+#include <linux/dma-contiguous.h>
+#endif
#ifdef __arch_page_to_dma
#error Please update to __arch_pfn_to_dma
@@ -172,6 +175,21 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
{
}
+#ifdef CONFIG_DMA_CMA
+static inline int dma_prepare_alloc_coherent(struct device *dev, size_t size)
+{
+ int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ int align = get_order(PAGE_ALIGN(size));
+
+ return dma_prepare_alloc_from_contiguous(dev, count, align);
+}
+#else
+static inline int dma_prepare_alloc_coherent(struct device *dev, size_t size)
+{
+ return 0;
+}
+#endif
+
/**
* dma_alloc_coherent - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git aosp-v3.0/arch/arm/include/asm/hardware/gic.h smdk4210/arch/arm/include/asm/hardware/gic.h
index 0691f9d..b665ccb 100644
--- aosp-v3.0/arch/arm/include/asm/hardware/gic.h
+++ smdk4210/arch/arm/include/asm/hardware/gic.h
@@ -37,10 +37,13 @@ extern void __iomem *gic_cpu_base_addr;
extern struct irq_chip gic_arch_extn;
void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
-void gic_secondary_init(unsigned int);
+void gic_secondary_init_base(unsigned int, void __iomem *, void __iomem *);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
void gic_enable_ppi(unsigned int);
+
+#define gic_secondary_init(n) gic_secondary_init_base((n), NULL, NULL)
+
#endif
#endif
diff --git aosp-v3.0/arch/arm/include/asm/hardware/pl330.h smdk4210/arch/arm/include/asm/hardware/pl330.h
index 575fa81..2f2753f 100644
--- aosp-v3.0/arch/arm/include/asm/hardware/pl330.h
+++ smdk4210/arch/arm/include/asm/hardware/pl330.h
@@ -165,6 +165,7 @@ struct pl330_req {
struct pl330_reqcfg *cfg;
/* Pointer to first xfer in the request. */
struct pl330_xfer *x;
+ unsigned int infiniteloop;
};
/*
diff --git aosp-v3.0/arch/arm/include/asm/hwcap.h smdk4210/arch/arm/include/asm/hwcap.h
index c1062c3..c93a22a 100644
--- aosp-v3.0/arch/arm/include/asm/hwcap.h
+++ smdk4210/arch/arm/include/asm/hwcap.h
@@ -4,22 +4,26 @@
/*
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
*/
-#define HWCAP_SWP 1
-#define HWCAP_HALF 2
-#define HWCAP_THUMB 4
-#define HWCAP_26BIT 8 /* Play it safe */
-#define HWCAP_FAST_MULT 16
-#define HWCAP_FPA 32
-#define HWCAP_VFP 64
-#define HWCAP_EDSP 128
-#define HWCAP_JAVA 256
-#define HWCAP_IWMMXT 512
-#define HWCAP_CRUNCH 1024
-#define HWCAP_THUMBEE 2048
-#define HWCAP_NEON 4096
-#define HWCAP_VFPv3 8192
-#define HWCAP_VFPv3D16 16384
-#define HWCAP_TLS 32768
+#define HWCAP_SWP (1 << 0)
+#define HWCAP_HALF (1 << 1)
+#define HWCAP_THUMB (1 << 2)
+#define HWCAP_26BIT (1 << 3) /* Play it safe */
+#define HWCAP_FAST_MULT (1 << 4)
+#define HWCAP_FPA (1 << 5)
+#define HWCAP_VFP (1 << 6)
+#define HWCAP_EDSP (1 << 7)
+#define HWCAP_JAVA (1 << 8)
+#define HWCAP_IWMMXT (1 << 9)
+#define HWCAP_CRUNCH (1 << 10)
+#define HWCAP_THUMBEE (1 << 11)
+#define HWCAP_NEON (1 << 12)
+#define HWCAP_VFPv3 (1 << 13)
+#define HWCAP_VFPv3D16 (1 << 14)
+#define HWCAP_TLS (1 << 15)
+#define HWCAP_VFPv4 (1 << 16)
+#define HWCAP_IDIVA (1 << 17)
+#define HWCAP_IDIVT (1 << 18)
+#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
/*
diff --git aosp-v3.0/arch/arm/include/asm/mach/map.h smdk4210/arch/arm/include/asm/mach/map.h
index d2fedb5..4bcef63 100644
--- aosp-v3.0/arch/arm/include/asm/mach/map.h
+++ smdk4210/arch/arm/include/asm/mach/map.h
@@ -29,6 +29,10 @@ struct map_desc {
#define MT_MEMORY_NONCACHED 11
#define MT_MEMORY_DTCM 12
#define MT_MEMORY_ITCM 13
+#ifdef CONFIG_DMA_CMA
+#define MT_MEMORY_SO 14
+#define MT_MEMORY_DMA_READY 15
+#endif
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
diff --git aosp-v3.0/arch/arm/include/asm/memory.h smdk4210/arch/arm/include/asm/memory.h
index af44a8f..2849f0b 100644
--- aosp-v3.0/arch/arm/include/asm/memory.h
+++ smdk4210/arch/arm/include/asm/memory.h
@@ -246,6 +246,7 @@ static inline void *phys_to_virt(phys_addr_t x)
*/
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
/*
diff --git aosp-v3.0/arch/arm/include/asm/outercache.h smdk4210/arch/arm/include/asm/outercache.h
index d838743..5adffd6 100644
--- aosp-v3.0/arch/arm/include/asm/outercache.h
+++ smdk4210/arch/arm/include/asm/outercache.h
@@ -29,6 +29,7 @@ struct outer_cache_fns {
void (*flush_range)(unsigned long, unsigned long);
void (*flush_all)(void);
void (*inv_all)(void);
+ void (*clean_all)(void);
void (*disable)(void);
#ifdef CONFIG_OUTER_CACHE_SYNC
void (*sync)(void);
@@ -68,6 +69,12 @@ static inline void outer_inv_all(void)
outer_cache.inv_all();
}
+static inline void outer_clean_all(void)
+{
+ if (outer_cache.clean_all)
+ outer_cache.clean_all();
+}
+
static inline void outer_disable(void)
{
if (outer_cache.disable)
@@ -84,6 +91,7 @@ static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
{ }
static inline void outer_flush_all(void) { }
static inline void outer_inv_all(void) { }
+static inline void outer_clean_all(void) { }
static inline void outer_disable(void) { }
#endif
diff --git aosp-v3.0/arch/arm/include/asm/perf_event.h smdk4210/arch/arm/include/asm/perf_event.h
index c4aa4e8..0f8e382 100644
--- aosp-v3.0/arch/arm/include/asm/perf_event.h
+++ smdk4210/arch/arm/include/asm/perf_event.h
@@ -24,6 +24,8 @@ enum arm_perf_pmu_ids {
ARM_PERF_PMU_ID_V6MP,
ARM_PERF_PMU_ID_CA8,
ARM_PERF_PMU_ID_CA9,
+ ARM_PERF_PMU_ID_CA5,
+ ARM_PERF_PMU_ID_CA15,
ARM_NUM_PMU_IDS,
};
diff --git aosp-v3.0/arch/arm/include/asm/sections.h smdk4210/arch/arm/include/asm/sections.h
index 2b8c516..adbd5af 100644
--- aosp-v3.0/arch/arm/include/asm/sections.h
+++ smdk4210/arch/arm/include/asm/sections.h
@@ -1 +1,9 @@
+#ifndef __ASM_ARM_SECTIONS_H
+#define __ASM_ARM_SECTIONS_H
+
#include <asm-generic/sections.h>
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+#endif /* __ASM_ARM_SECTIONS_H */
diff --git aosp-v3.0/arch/arm/include/asm/setup.h smdk4210/arch/arm/include/asm/setup.h
index ee2ad8a..4b0294d 100644
--- aosp-v3.0/arch/arm/include/asm/setup.h
+++ smdk4210/arch/arm/include/asm/setup.h
@@ -192,7 +192,9 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
/*
* Memory map description
*/
+#ifndef NR_BANKS
#define NR_BANKS 8
+#endif
struct membank {
phys_addr_t start;
diff --git aosp-v3.0/arch/arm/include/asm/tlb.h smdk4210/arch/arm/include/asm/tlb.h
index 265f908..0504364 100644
--- aosp-v3.0/arch/arm/include/asm/tlb.h
+++ smdk4210/arch/arm/include/asm/tlb.h
@@ -198,7 +198,15 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
pgtable_page_dtor(pte);
- tlb_add_flush(tlb, addr);
+
+ /*
+ * With the classic ARM MMU, a pte page has two corresponding pmd
+ * entries, each covering 1MB.
+ */
+ addr &= PMD_MASK;
+ tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+ tlb_add_flush(tlb, addr + SZ_1M);
+
tlb_remove_page(tlb, pte);
}
diff --git aosp-v3.0/arch/arm/kernel/Makefile smdk4210/arch/arm/kernel/Makefile
index a5b31af..6dccbbf 100644
--- aosp-v3.0/arch/arm/kernel/Makefile
+++ smdk4210/arch/arm/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
+obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
obj-$(CONFIG_OF) += devtree.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
diff --git aosp-v3.0/arch/arm/kernel/perf_event.c smdk4210/arch/arm/kernel/perf_event.c
index 2b5b142..3132699 100644
--- aosp-v3.0/arch/arm/kernel/perf_event.c
+++ smdk4210/arch/arm/kernel/perf_event.c
@@ -662,6 +662,12 @@ init_hw_perf_events(void)
case 0xC090: /* Cortex-A9 */
armpmu = armv7_a9_pmu_init();
break;
+ case 0xC050: /* Cortex-A5 */
+ armpmu = armv7_a5_pmu_init();
+ break;
+ case 0xC0F0: /* Cortex-A15 */
+ armpmu = armv7_a15_pmu_init();
+ break;
}
/* Intel CPUs [xscale]. */
} else if (0x69 == implementor) {
diff --git aosp-v3.0/arch/arm/kernel/perf_event_v7.c smdk4210/arch/arm/kernel/perf_event_v7.c
index 4372763..462aefb 100644
--- aosp-v3.0/arch/arm/kernel/perf_event_v7.c
+++ smdk4210/arch/arm/kernel/perf_event_v7.c
@@ -17,17 +17,23 @@
*/
#ifdef CONFIG_CPU_V7
-/* Common ARMv7 event types */
+/*
+ * Common ARMv7 event types
+ *
+ * Note: An implementation may not be able to count all of these events
+ * but the encodings are considered to be `reserved' in the case that
+ * they are not available.
+ */
enum armv7_perf_types {
ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
ARMV7_PERFCTR_IFETCH_MISS = 0x01,
ARMV7_PERFCTR_ITLB_MISS = 0x02,
- ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
- ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
+ ARMV7_PERFCTR_DCACHE_REFILL = 0x03, /* L1 */
+ ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, /* L1 */
ARMV7_PERFCTR_DTLB_REFILL = 0x05,
ARMV7_PERFCTR_DREAD = 0x06,
ARMV7_PERFCTR_DWRITE = 0x07,
-
+ ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
ARMV7_PERFCTR_EXC_TAKEN = 0x09,
ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
ARMV7_PERFCTR_CID_WRITE = 0x0B,
@@ -39,21 +45,30 @@ enum armv7_perf_types {
*/
ARMV7_PERFCTR_PC_WRITE = 0x0C,
ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
+ ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
+
+ /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
-
- ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
+ ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
+ ARMV7_PERFCTR_MEM_ACCESS = 0x13,
+ ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
+ ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
+ ARMV7_PERFCTR_L2_DCACHE_ACCESS = 0x16,
+ ARMV7_PERFCTR_L2_DCACHE_REFILL = 0x17,
+ ARMV7_PERFCTR_L2_DCACHE_WB = 0x18,
+ ARMV7_PERFCTR_BUS_ACCESS = 0x19,
+ ARMV7_PERFCTR_MEMORY_ERROR = 0x1A,
+ ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
+ ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
+ ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
ARMV7_PERFCTR_CPU_CYCLES = 0xFF
};
/* ARMv7 Cortex-A8 specific event types */
enum armv7_a8_perf_types {
- ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
-
- ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
-
ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
@@ -138,6 +153,39 @@ enum armv7_a9_perf_types {
ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
};
+/* ARMv7 Cortex-A5 specific event types */
+enum armv7_a5_perf_types {
+ ARMV7_PERFCTR_IRQ_TAKEN = 0x86,
+ ARMV7_PERFCTR_FIQ_TAKEN = 0x87,
+
+ ARMV7_PERFCTR_EXT_MEM_RQST = 0xc0,
+ ARMV7_PERFCTR_NC_EXT_MEM_RQST = 0xc1,
+ ARMV7_PERFCTR_PREFETCH_LINEFILL = 0xc2,
+ ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
+ ARMV7_PERFCTR_ENTER_READ_ALLOC = 0xc4,
+ ARMV7_PERFCTR_READ_ALLOC = 0xc5,
+
+ ARMV7_PERFCTR_STALL_SB_FULL = 0xc9,
+};
+
+/* ARMv7 Cortex-A15 specific event types */
+enum armv7_a15_perf_types {
+ ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40,
+ ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41,
+ ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42,
+ ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43,
+
+ ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C,
+ ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D,
+
+ ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50,
+ ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51,
+ ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52,
+ ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53,
+
+ ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76,
+};
+
/*
* Cortex-A8 HW events mapping
*
@@ -207,11 +255,6 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
},
},
[C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
@@ -323,11 +366,6 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
},
},
[C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
@@ -374,6 +412,242 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
};
/*
+ * Cortex-A5 HW events mapping
+ */
+static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ /*
+ * The prefetch counters don't differentiate between the I
+ * side and the D side.
+ */
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
+ * Cortex-A15 HW events mapping
+ */
+static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ /*
+ * Not all performance counters differentiate between read
+ * and write accesses/misses so we're not always strictly
+ * correct, but it's the best we can do. Writes and reads get
+ * combined in these cases.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
* Perf Events counters
*/
enum armv7_counters {
@@ -905,6 +1179,26 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
armv7pmu.num_events = armv7_read_num_pmnc_events();
return &armv7pmu;
}
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA5;
+ armv7pmu.name = "ARMv7 Cortex-A5";
+ armv7pmu.cache_map = &armv7_a5_perf_cache_map;
+ armv7pmu.event_map = &armv7_a5_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA15;
+ armv7pmu.name = "ARMv7 Cortex-A15";
+ armv7pmu.cache_map = &armv7_a15_perf_cache_map;
+ armv7pmu.event_map = &armv7_a15_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
#else
static const struct arm_pmu *__init armv7_a8_pmu_init(void)
{
@@ -915,4 +1209,14 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
{
return NULL;
}
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+ return NULL;
+}
#endif /* CONFIG_CPU_V7 */
diff --git aosp-v3.0/arch/arm/kernel/setup.c smdk4210/arch/arm/kernel/setup.c
index acbb447..7e51962 100644
--- aosp-v3.0/arch/arm/kernel/setup.c
+++ smdk4210/arch/arm/kernel/setup.c
@@ -49,6 +49,9 @@
#include <asm/mach/time.h>
#include <asm/traps.h>
#include <asm/unwind.h>
+#ifdef CONFIG_MIDAS_COMMON
+#include <plat/cpu.h>
+#endif
#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
#include "compat.h"
@@ -75,6 +78,9 @@ __setup("fpe=", fpe_setup);
extern void paging_init(struct machine_desc *desc);
extern void sanity_check_meminfo(void);
extern void reboot_setup(char *str);
+#ifdef CONFIG_DMA_CMA
+extern void setup_dma_zone(struct machine_desc *desc);
+#endif
unsigned int processor_id;
EXPORT_SYMBOL(processor_id);
@@ -887,6 +893,9 @@ void __init setup_arch(char **cmdline_p)
machine_desc = mdesc;
machine_name = mdesc->name;
+#ifdef CONFIG_DMA_CMA
+ setup_dma_zone(mdesc);
+#endif
if (mdesc->soft_reboot)
reboot_setup("s");
@@ -979,6 +988,10 @@ static const char *hwcap_str[] = {
"neon",
"vfpv3",
"vfpv3d16",
+ "tls",
+ "vfpv4",
+ "idiva",
+ "idivt",
NULL
};
@@ -1037,6 +1050,10 @@ static int c_show(struct seq_file *m, void *v)
seq_puts(m, "\n");
+#ifdef CONFIG_MIDAS_COMMON
+ if (soc_is_exynos4412())
+ seq_printf(m, "Chip revision\t: %04x\n", samsung_rev());
+#endif
seq_printf(m, "Hardware\t: %s\n", machine_name);
seq_printf(m, "Revision\t: %04x\n", system_rev);
seq_printf(m, "Serial\t\t: %08x%08x\n",
diff --git aosp-v3.0/arch/arm/kernel/smp.c smdk4210/arch/arm/kernel/smp.c
index 9739bb8..ffc8fb6 100644
--- aosp-v3.0/arch/arm/kernel/smp.c
+++ smdk4210/arch/arm/kernel/smp.c
@@ -40,6 +40,8 @@
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <mach/sec_debug.h>
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -272,6 +274,20 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
}
/*
+ * Skip the secondary calibration on architectures sharing clock
+ * with primary cpu. Archs can use ARCH_SKIP_SECONDARY_CALIBRATE
+ * for this.
+ */
+static inline int skip_secondary_calibrate(void)
+{
+#ifdef CONFIG_ARCH_SKIP_SECONDARY_CALIBRATE
+ return 0;
+#else
+ return -ENXIO;
+#endif
+}
+
+/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
@@ -280,8 +296,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
- printk("CPU%u: Booted secondary processor\n", cpu);
-
/*
* All kernel threads share the same mm context; grab a
* reference and switch to it.
@@ -293,6 +307,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
enter_lazy_tlb(mm, current);
local_flush_tlb_all();
+ printk("CPU%u: Booted secondary processor\n", cpu);
+
cpu_init();
preempt_disable();
trace_hardirqs_off();
@@ -304,7 +320,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
notify_cpu_starting(cpu);
- calibrate_delay();
+ if (skip_secondary_calibrate())
+ calibrate_delay();
smp_store_cpu_info(cpu);
@@ -320,13 +337,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/
percpu_timer_setup();
- while (!cpu_active(cpu))
- cpu_relax();
-
- /*
- * cpu_active bit is set, so it's safe to enable interrupts
- * now.
- */
local_irq_enable();
local_fiq_enable();
@@ -450,9 +460,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
static void ipi_timer(void)
{
struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
- irq_enter();
evt->event_handler(evt);
- irq_exit();
}
#ifdef CONFIG_LOCAL_TIMERS
@@ -463,8 +471,13 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
if (local_timer_ack()) {
__inc_irq_stat(cpu, local_timer_irqs);
+ sec_debug_irq_log(0, do_local_timer, 1);
+ irq_enter();
ipi_timer();
- }
+ irq_exit();
+ sec_debug_irq_log(0, do_local_timer, 2);
+ } else
+ sec_debug_irq_log(0, do_local_timer, 3);
set_irq_regs(old_regs);
}
@@ -556,6 +569,9 @@ static void ipi_cpu_stop(unsigned int cpu)
local_fiq_disable();
local_irq_disable();
+ flush_cache_all();
+ local_flush_tlb_all();
+
while (1)
cpu_relax();
}
@@ -623,9 +639,13 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
+ sec_debug_irq_log(ipinr, do_IPI, 1);
+
switch (ipinr) {
case IPI_TIMER:
+ irq_enter();
ipi_timer();
+ irq_exit();
break;
case IPI_RESCHEDULE:
@@ -633,15 +653,21 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
break;
case IPI_CALL_FUNC:
+ irq_enter();
generic_smp_call_function_interrupt();
+ irq_exit();
break;
case IPI_CALL_FUNC_SINGLE:
+ irq_enter();
generic_smp_call_function_single_interrupt();
+ irq_exit();
break;
case IPI_CPU_STOP:
+ irq_enter();
ipi_cpu_stop(cpu);
+ irq_exit();
break;
case IPI_CPU_BACKTRACE:
@@ -653,6 +679,9 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
cpu, ipinr);
break;
}
+
+ sec_debug_irq_log(ipinr, do_IPI, 2);
+
set_irq_regs(old_regs);
}
@@ -688,3 +717,13 @@ int setup_profiling_timer(unsigned int multiplier)
{
return -EINVAL;
}
+
+static void flush_all_cpu_cache(void *info)
+{
+ flush_cache_all();
+}
+
+void flush_all_cpu_caches(void)
+{
+ on_each_cpu(flush_all_cpu_cache, NULL, 1);
+}
diff --git aosp-v3.0/arch/arm/kernel/smp_scu.c smdk4210/arch/arm/kernel/smp_scu.c
index cb7dd40..1936649 100644
--- aosp-v3.0/arch/arm/kernel/smp_scu.c
+++ smdk4210/arch/arm/kernel/smp_scu.c
@@ -15,12 +15,18 @@
#include <asm/cacheflush.h>
#include <asm/cputype.h>
+#include <plat/cpu.h>
+
#define SCU_CTRL 0x00
#define SCU_CONFIG 0x04
#define SCU_CPU_STATUS 0x08
#define SCU_INVALIDATE 0x0c
#define SCU_FPGA_REVISION 0x10
+#ifdef CONFIG_MACH_PX
+extern void logbuf_force_unlock(void);
+#endif
+
/*
* Get the number of CPU cores from the SCU configuration
*/
@@ -33,7 +39,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)
/*
* Enable the SCU
*/
-void __init scu_enable(void __iomem *scu_base)
+void scu_enable(void __iomem *scu_base)
{
u32 scu_ctrl;
@@ -51,6 +57,10 @@ void __init scu_enable(void __iomem *scu_base)
if (scu_ctrl & 1)
return;
+ if ((soc_is_exynos4412() && (samsung_rev() >= EXYNOS4412_REV_1_0)) ||
+ soc_is_exynos4210())
+ scu_ctrl |= (1<<3);
+
scu_ctrl |= 1;
__raw_writel(scu_ctrl, scu_base + SCU_CTRL);
@@ -59,6 +69,10 @@ void __init scu_enable(void __iomem *scu_base)
* initialised is visible to the other CPUs.
*/
flush_cache_all();
+
+#ifdef CONFIG_MACH_PX
+ logbuf_force_unlock();
+#endif
}
/*
diff --git aosp-v3.0/arch/arm/kernel/stacktrace.c smdk4210/arch/arm/kernel/stacktrace.c
index 381d23a..b3337e7 100644
--- aosp-v3.0/arch/arm/kernel/stacktrace.c
+++ smdk4210/arch/arm/kernel/stacktrace.c
@@ -94,20 +94,19 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
if (tsk != current) {
#ifdef CONFIG_SMP
/*
- * What guarantees do we have here that 'tsk' is not
- * running on another CPU? For now, ignore it as we
- * can't guarantee we won't explode.
+ * What guarantees do we have here that 'tsk'
+ * is not running on another CPU?
+ *
+ * We guarantee that this function will be used for
+ * latencytop only :-)
*/
- if (trace->nr_entries < trace->max_entries)
- trace->entries[trace->nr_entries++] = ULONG_MAX;
- return;
-#else
+ /* BUG(); */
+#endif
data.no_sched_functions = 1;
frame.fp = thread_saved_fp(tsk);
frame.sp = thread_saved_sp(tsk);
frame.lr = 0; /* recovered from the stack */
frame.pc = thread_saved_pc(tsk);
-#endif
} else {
register unsigned long current_sp asm ("sp");
diff --git aosp-v3.0/arch/arm/lib/copy_from_user.S smdk4210/arch/arm/lib/copy_from_user.S
index 66a477a..54daeae 100644
--- aosp-v3.0/arch/arm/lib/copy_from_user.S
+++ smdk4210/arch/arm/lib/copy_from_user.S
@@ -68,6 +68,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldr1w \src, \reg1, \abort
+ ldr1w \src, \reg2, \abort
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
diff --git aosp-v3.0/arch/arm/lib/copy_template.S smdk4210/arch/arm/lib/copy_template.S
index 805e3f8..f2b5885 100644
--- aosp-v3.0/arch/arm/lib/copy_template.S
+++ smdk4210/arch/arm/lib/copy_template.S
@@ -66,6 +66,7 @@
* than one 32bit instruction in Thumb-2)
*/
+#define PLDSIZE (CONFIG_ARM_PLD_SIZE)
enter r4, lr
@@ -90,19 +91,46 @@
CALGN( add pc, r4, ip )
PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
+
+#if (PLDSIZE == 64)
+2: PLD( cmp r2, #32)
+ PLD( blt .32copy)
+
+.64copy:
+ PLD( subs r2, r2, #(PLDSIZE*3+32) )
+ PLD( pld [r1, #PLDSIZE-4] )
PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
+ PLD( pld [r1, #PLDSIZE*2-4] )
+ PLD( pld [r1, #PLDSIZE*3-4] )
+3: PLD( pld [r1, #PLDSIZE*4-4] )
+4: cpy8w r0, r1, r4, r5, abort=20f
+ cpy8w r0, r1, r4, r5, abort=20f
+ subs r2, r2, #PLDSIZE
+ bge 3b
+ PLD( cmn r2, #(PLDSIZE*3) )
+ PLD( bge 4b )
+
+ PLD( cmn r2, #(PLDSIZE*4-32) )
+ PLD( blt 5f)
+
+.32copy:
+ cpy8w r0, r1, r4, r5, abort=20f
+#else
+2: PLD( subs r2, r2, #(PLDSIZE*3) )
+ PLD( pld [r1, #(PLDSIZE-4)] )
+ PLD( blt 4f )
+ PLD( pld [r1, #(PLDSIZE*2-4)] )
+ PLD( pld [r1, #(PLDSIZE*3-4)] )
+
+3: PLD( pld [r1, #(PLDSIZE*4-4)] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #PLDSIZE
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
bge 3b
- PLD( cmn r2, #96 )
+ PLD( cmn r2, #(PLDSIZE*3) )
PLD( bge 4b )
+#endif
5: ands ip, r2, #28
rsb ip, ip, #32
diff --git aosp-v3.0/arch/arm/lib/copy_to_user.S smdk4210/arch/arm/lib/copy_to_user.S
index d066df6..e32788b 100644
--- aosp-v3.0/arch/arm/lib/copy_to_user.S
+++ smdk4210/arch/arm/lib/copy_to_user.S
@@ -71,6 +71,15 @@
str1w \ptr, \reg8, \abort
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ str1w \dst, \reg1, \abort
+ str1w \dst, \reg2, \abort
+ .endr
+ add \src, \src, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm
diff --git aosp-v3.0/arch/arm/lib/memcpy.S smdk4210/arch/arm/lib/memcpy.S
index a9b9e22..7ffda59 100644
--- aosp-v3.0/arch/arm/lib/memcpy.S
+++ smdk4210/arch/arm/lib/memcpy.S
@@ -40,6 +40,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \src, \src, #32
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
diff --git aosp-v3.0/arch/arm/mach-s3c2410/include/mach/dma.h smdk4210/arch/arm/mach-s3c2410/include/mach/dma.h
index b2b2a5b..ad44a3d 100644
--- aosp-v3.0/arch/arm/mach-s3c2410/include/mach/dma.h
+++ smdk4210/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -201,4 +201,8 @@ static inline bool s3c_dma_has_circular(void)
return false;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return false;
+}
#endif /* __ASM_ARCH_DMA_H */
diff --git aosp-v3.0/arch/arm/mach-s3c2410/include/mach/pm-core.h smdk4210/arch/arm/mach-s3c2410/include/mach/pm-core.h
index 70a83b2..45eea52 100644
--- aosp-v3.0/arch/arm/mach-s3c2410/include/mach/pm-core.h
+++ smdk4210/arch/arm/mach-s3c2410/include/mach/pm-core.h
@@ -62,3 +62,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void s3c_pm_saved_gpios(void) { }
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/Kconfig smdk4210/arch/arm/mach-s3c64xx/Kconfig
index e4177e2..fdc89fc 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/Kconfig
+++ smdk4210/arch/arm/mach-s3c64xx/Kconfig
@@ -142,6 +142,7 @@ config MACH_SMDK6410
select S3C_DEV_USB_HOST
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select HAVE_S3C2410_WATCHDOG if WATCHDOG
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/cpu.c smdk4210/arch/arm/mach-s3c64xx/cpu.c
index 374e45e..6c498f9 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/cpu.c
+++ smdk4210/arch/arm/mach-s3c64xx/cpu.c
@@ -43,16 +43,16 @@ static const char name_s3c6410[] = "S3C6410";
static struct cpu_table cpu_ids[] __initdata = {
{
- .idcode = 0x36400000,
- .idmask = 0xfffff000,
+ .idcode = S3C6400_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
.map_io = s3c6400_map_io,
.init_clocks = s3c6400_init_clocks,
.init_uarts = s3c6400_init_uarts,
.init = s3c6400_init,
.name = name_s3c6400,
}, {
- .idcode = 0x36410100,
- .idmask = 0xffffff00,
+ .idcode = S3C6410_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
.map_io = s3c6410_map_io,
.init_clocks = s3c6410_init_clocks,
.init_uarts = s3c6410_init_uarts,
@@ -140,22 +140,14 @@ void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
{
- unsigned long idcode;
-
/* initialise the io descriptors we need for initialisation */
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
iotable_init(mach_desc, size);
- idcode = __raw_readl(S3C_VA_SYS + 0x118);
- if (!idcode) {
- /* S3C6400 has the ID register in a different place,
- * and needs a write before it can be read. */
-
- __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
- idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
- }
+ /* detect cpu id */
+ s3c64xx_init_cpu();
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
static __init int s3c64xx_sysdev_init(void)
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/dev-onenand1.c smdk4210/arch/arm/mach-s3c64xx/dev-onenand1.c
index 92ffd5b..999f9e1 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/dev-onenand1.c
+++ smdk4210/arch/arm/mach-s3c64xx/dev-onenand1.c
@@ -19,6 +19,8 @@
#include <mach/irqs.h>
#include <mach/map.h>
+#include <plat/devs.h>
+
static struct resource s3c64xx_onenand1_resources[] = {
[0] = {
.start = S3C64XX_PA_ONENAND1,
@@ -46,10 +48,6 @@ struct platform_device s3c64xx_device_onenand1 = {
void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
{
- struct onenand_platform_data *pd;
-
- pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
- if (!pd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- s3c64xx_device_onenand1.dev.platform_data = pd;
+ s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
+ &s3c64xx_device_onenand1);
}
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/include/mach/dma.h smdk4210/arch/arm/mach-s3c64xx/include/mach/dma.h
index 0a5d926..9e14383 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ smdk4210/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -63,6 +63,11 @@ static __inline__ bool s3c_dma_has_circular(void)
return true;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return false;
+}
+
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/include/mach/pm-core.h smdk4210/arch/arm/mach-s3c64xx/include/mach/pm-core.h
index 1e9f20f..38659be 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+++ smdk4210/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -53,7 +53,7 @@ static inline void s3c_pm_arch_show_resume_irqs(void)
* the IRQ wake controls depending on the CPU we are running on */
#define s3c_irqwake_eintallow ((1 << 28) - 1)
-#define s3c_irqwake_intallow (0)
+#define s3c_irqwake_intallow (~0)
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
@@ -96,3 +96,20 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
save->ucon = new_ucon;
}
}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* ensure sleep mode has been cleared from the system */
+
+ __raw_writel(0, S3C64XX_SLPEN);
+}
+
+static inline void s3c_pm_saved_gpios(void)
+{
+ /* turn on the sleep mode and keep it there, as it seems that during
+ * suspend the xCON registers get re-set and thus you can end up with
+ * problems between going to sleep and resuming.
+ */
+
+ __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
+}
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/irq.c smdk4210/arch/arm/mach-s3c64xx/irq.c
index 97660c8..75d9a0e 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/irq.c
+++ smdk4210/arch/arm/mach-s3c64xx/irq.c
@@ -48,14 +48,22 @@ static struct s3c_uart_irq uart_irqs[] = {
},
};
+/* setup the sources the vic should advertise resume for, even though it
+ * is not doing the wake (set_irq_wake needs to be valid) */
+#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
+#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */
- vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0);
- vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0);
+ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
+ vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
/* add the timer sub-irqs */
s3c_init_vic_timer_irq(5, IRQ_TIMER0);
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-anw6410.c smdk4210/arch/arm/mach-s3c64xx/mach-anw6410.c
index a53cf14..cb88643 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -35,7 +35,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -44,6 +43,7 @@
#include <plat/regs-serial.h>
#include <plat/iic.h>
#include <plat/fb.h>
+#include <plat/regs-fb-v4.h>
#include <mach/s3c6410.h>
#include <plat/clock.h>
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-hmt.c smdk4210/arch/arm/mach-s3c64xx/mach-hmt.c
index b263958..b3d93cc 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-hmt.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -27,7 +27,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -42,6 +41,7 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-mini6410.c smdk4210/arch/arm/mach-s3c64xx/mach-mini6410.c
index 89f35e0..527f49b 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -29,7 +29,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
@@ -42,6 +41,7 @@
#include <plat/nand.h>
#include <plat/regs-serial.h>
#include <plat/ts.h>
+#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-ncp.c smdk4210/arch/arm/mach-s3c64xx/mach-ncp.c
index c498649..01c6857 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-ncp.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -30,7 +30,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -44,6 +43,7 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-real6410.c smdk4210/arch/arm/mach-s3c64xx/mach-real6410.c
index 4957ab0..95b04b1 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-real6410.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -30,7 +30,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
@@ -43,6 +42,7 @@
#include <plat/nand.h>
#include <plat/regs-serial.h>
#include <plat/ts.h>
+#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-smartq5.c smdk4210/arch/arm/mach-s3c64xx/mach-smartq5.c
index 3a3e5ac..342e8df 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -21,7 +21,6 @@
#include <asm/mach/arch.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/s3c6410.h>
@@ -29,6 +28,7 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
+#include <plat/regs-fb-v4.h>
#include "mach-smartq.h"
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-smartq7.c smdk4210/arch/arm/mach-s3c64xx/mach-smartq7.c
index e653758..5796397 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -21,7 +21,6 @@
#include <asm/mach/arch.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/s3c6410.h>
@@ -29,6 +28,7 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
+#include <plat/regs-fb-v4.h>
#include "mach-smartq.h"
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/mach-smdk6410.c smdk4210/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2c0353a..ecbea92 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ smdk4210/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -48,7 +48,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -71,6 +70,8 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/keypad.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
@@ -209,17 +210,9 @@ static struct platform_device smdk6410_smsc911x = {
};
#ifdef CONFIG_REGULATOR
-static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
- {
- /* WM8580 */
- .supply = "PVDD",
- .dev_name = "0-001b",
- },
- {
- /* WM8580 */
- .supply = "AVDD",
- .dev_name = "0-001b",
- },
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] __initdata = {
+ REGULATOR_SUPPLY("PVDD", "0-001b"),
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
};
static struct regulator_init_data smdk6410_b_pwr_5v_data = {
@@ -337,16 +330,12 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_rtc,
&s3c_device_ts,
&s3c_device_wdt,
- &s3c_device_timer[1],
- &smdk6410_backlight_device,
};
#ifdef CONFIG_REGULATOR
/* ARM core */
static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
- {
- .supply = "vddarm",
- }
+ REGULATOR_SUPPLY("vddarm", NULL),
};
/* VDDARM, BUCK1 on J5 */
@@ -484,11 +473,7 @@ static struct regulator_init_data wm8350_dcdc3_data = {
/* USB, EXT, PCM, ADC/DAC, USB, MMC */
static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
- {
- /* WM8580 */
- .supply = "DVDD",
- .dev_name = "0-001b",
- },
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
};
static struct regulator_init_data wm8350_dcdc4_data = {
@@ -599,7 +584,7 @@ static struct regulator_init_data wm1192_dcdc3 = {
};
static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
- { .supply = "DVDD", .dev_name = "0-001b", }, /* WM8580 */
+ REGULATOR_SUPPLY("DVDD", "0-001b"), /* WM8580 */
};
static struct regulator_init_data wm1192_ldo1 = {
@@ -679,6 +664,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
+ .no = S3C64XX_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6410_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6410_map_io(void)
{
u32 tmp;
@@ -740,6 +735,8 @@ static void __init smdk6410_machine_init(void)
s3c_ide_set_platdata(&smdk6410_ide_pdata);
+ samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
+
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s3c64xx/setup-fb-24bpp.c smdk4210/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 8f30911..83d2afb 100644
--- aosp-v3.0/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
+++ smdk4210/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -17,7 +17,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
diff --git aosp-v3.0/arch/arm/mach-s5p64x0/Kconfig smdk4210/arch/arm/mach-s5p64x0/Kconfig
index 017af4c..65c7518 100644
--- aosp-v3.0/arch/arm/mach-s5p64x0/Kconfig
+++ smdk4210/arch/arm/mach-s5p64x0/Kconfig
@@ -36,6 +36,7 @@ config MACH_SMDK6440
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_I2C1
@@ -50,6 +51,7 @@ config MACH_SMDK6450
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_I2C1
diff --git aosp-v3.0/arch/arm/mach-s5p64x0/mach-smdk6440.c smdk4210/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 2d559f1..346f8df 100644
--- aosp-v3.0/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ smdk4210/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -46,6 +46,7 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/s5p-time.h>
+#include <plat/backlight.h>
#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -91,45 +92,6 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
},
};
-static int smdk6440_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5P6440_GPF(15), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5P6440_GPF15_PWM_TOUT1 */
- s3c_gpio_cfgpin(S5P6440_GPF(15), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdk6440_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5P6440_GPF(15), S3C_GPIO_OUTPUT);
- gpio_free(S5P6440_GPF(15));
-}
-
-static struct platform_pwm_backlight_data smdk6440_backlight_data = {
- .pwm_id = 1,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdk6440_backlight_init,
- .exit = smdk6440_backlight_exit,
-};
-
-static struct platform_device smdk6440_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[1].dev,
- .platform_data = &smdk6440_backlight_data,
- },
-};
-
static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_rtc,
@@ -139,8 +101,6 @@ static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6440_device_iis,
- &s3c_device_timer[1],
- &smdk6440_backlight_device,
};
static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -175,6 +135,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6440_bl_gpio_info = {
+ .no = S5P6440_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6440_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6440_map_io(void)
{
s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
@@ -194,6 +164,8 @@ static void __init smdk6440_machine_init(void)
i2c_register_board_info(1, smdk6440_i2c_devs1,
ARRAY_SIZE(smdk6440_i2c_devs1));
+ samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
+
platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s5p64x0/mach-smdk6450.c smdk4210/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d19c469..33f2adf 100644
--- aosp-v3.0/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ smdk4210/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -46,6 +46,7 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/s5p-time.h>
+#include <plat/backlight.h>
#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -109,45 +110,6 @@ static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
#endif
};
-static int smdk6450_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5P6450_GPF(15), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5P6450_GPF15_PWM_TOUT1 */
- s3c_gpio_cfgpin(S5P6450_GPF(15), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdk6450_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5P6450_GPF(15), S3C_GPIO_OUTPUT);
- gpio_free(S5P6450_GPF(15));
-}
-
-static struct platform_pwm_backlight_data smdk6450_backlight_data = {
- .pwm_id = 1,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdk6450_backlight_init,
- .exit = smdk6450_backlight_exit,
-};
-
-static struct platform_device smdk6450_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[1].dev,
- .platform_data = &smdk6450_backlight_data,
- },
-};
-
static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_rtc,
@@ -157,8 +119,6 @@ static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6450_device_iis0,
- &s3c_device_timer[1],
- &smdk6450_backlight_device,
/* s5p6450_device_spi0 will be added */
};
@@ -194,6 +154,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6450_bl_gpio_info = {
+ .no = S5P6450_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6450_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6450_map_io(void)
{
s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
@@ -213,6 +183,8 @@ static void __init smdk6450_machine_init(void)
i2c_register_board_info(1, smdk6450_i2c_devs1,
ARRAY_SIZE(smdk6450_i2c_devs1));
+ samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
+
platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s5pc100/Kconfig smdk4210/arch/arm/mach-s5pc100/Kconfig
index 608722f..e8a33c4 100644
--- aosp-v3.0/arch/arm/mach-s5pc100/Kconfig
+++ smdk4210/arch/arm/mach-s5pc100/Kconfig
@@ -56,6 +56,7 @@ config MACH_SMDKC100
select S3C_DEV_RTC
select S3C_DEV_WDT
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
diff --git aosp-v3.0/arch/arm/mach-s5pc100/clock.c smdk4210/arch/arm/mach-s5pc100/clock.c
index 0305e9b..da2ea0a 100644
--- aosp-v3.0/arch/arm/mach-s5pc100/clock.c
+++ smdk4210/arch/arm/mach-s5pc100/clock.c
@@ -976,48 +976,13 @@ struct clksrc_sources clk_src_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
};
-static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
-{
- struct clk *pclk;
- int ret;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- ret = pclk->ops->set_rate(pclk, rate);
- clk_put(pclk);
-
- return ret;
-}
-
-static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
-{
- struct clk *pclk;
- int rate;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- rate = pclk->ops->get_rate(clk);
- clk_put(pclk);
-
- return rate;
-}
-
-static struct clk_ops s5pc100_sclk_spdif_ops = {
- .set_rate = s5pc100_spdif_set_rate,
- .get_rate = s5pc100_spdif_get_rate,
-};
-
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.ctrlbit = (1 << 11),
.enable = s5pc100_sclk1_ctrl,
- .ops = &s5pc100_sclk_spdif_ops,
+ .ops = &s5p_sclk_spdif_ops,
},
.sources = &clk_src_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
diff --git aosp-v3.0/arch/arm/mach-s5pc100/mach-smdkc100.c smdk4210/arch/arm/mach-s5pc100/mach-smdkc100.c
index 0525cb3..227d890 100644
--- aosp-v3.0/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ smdk4210/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -29,7 +29,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <video/platform_lcd.h>
@@ -51,6 +50,8 @@
#include <plat/keypad.h>
#include <plat/ts.h>
#include <plat/audio.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -179,45 +180,6 @@ static struct samsung_keypad_platdata smdkc100_keypad_data __initdata = {
.cols = 8,
};
-static int smdkc100_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5PC100_GPD(0), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT0\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5PC100_GPD_TOUT_0 */
- s3c_gpio_cfgpin(S5PC100_GPD(0), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdkc100_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5PC100_GPD(0), S3C_GPIO_OUTPUT);
- gpio_free(S5PC100_GPD(0));
-}
-
-static struct platform_pwm_backlight_data smdkc100_backlight_data = {
- .pwm_id = 0,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdkc100_backlight_init,
- .exit = smdkc100_backlight_exit,
-};
-
-static struct platform_device smdkc100_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[0].dev,
- .platform_data = &smdkc100_backlight_data,
- },
-};
-
static struct platform_device *smdkc100_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
@@ -239,8 +201,6 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s5p_device_fimc1,
&s5p_device_fimc2,
&s5pc100_device_spdif,
- &s3c_device_timer[0],
- &smdkc100_backlight_device,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -249,6 +209,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkc100_bl_gpio_info = {
+ .no = S5PC100_GPD(0),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkc100_bl_data = {
+ .pwm_id = 0,
+};
+
static void __init smdkc100_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -276,6 +246,9 @@ static void __init smdkc100_machine_init(void)
/* LCD init */
gpio_request(S5PC100_GPH0(6), "GPH0");
smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
+
+ samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
+
platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s5pc100/setup-fb-24bpp.c smdk4210/arch/arm/mach-s5pc100/setup-fb-24bpp.c
index d31c0f3..8978e4c 100644
--- aosp-v3.0/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+++ smdk4210/arch/arm/mach-s5pc100/setup-fb-24bpp.c
@@ -15,7 +15,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
diff --git aosp-v3.0/arch/arm/mach-s5pv210/Kconfig smdk4210/arch/arm/mach-s5pv210/Kconfig
index 37b5a97..057a850 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/Kconfig
+++ smdk4210/arch/arm/mach-s5pv210/Kconfig
@@ -18,6 +18,11 @@ config CPU_S5PV210
help
Enable S5PV210 CPU support
+config CPU_S5PC110
+ bool
+ help
+ S5PC110(MCP) is one of package option of S5PV210.
+
config S5PV210_SETUP_I2C1
bool
help
@@ -105,14 +110,29 @@ config MACH_GONI
config MACH_SMDKC110
bool "SMDKC110"
select CPU_S5PV210
+ select CPU_S5PC110
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_IDE
+ select S5PV210_SETUP_KEYPAD
+ select S5PV210_SETUP_SDHCI
+ select HAVE_PWM
help
Machine support for Samsung SMDKC110
S5PC110(MCP) is one of package option of S5PV210
@@ -134,6 +154,7 @@ config MACH_SMDKV210
select S3C_DEV_RTC
select S3C_DEV_WDT
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
@@ -144,6 +165,7 @@ config MACH_SMDKV210
select S5PV210_SETUP_IDE
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
+ select HAVE_PWM
help
Machine support for Samsung SMDKV210
diff --git aosp-v3.0/arch/arm/mach-s5pv210/Makefile smdk4210/arch/arm/mach-s5pv210/Makefile
index 50907ac..c3cd02a 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/Makefile
+++ smdk4210/arch/arm/mach-s5pv210/Makefile
@@ -5,7 +5,7 @@
#
# Licensed under GPLv2
-obj-y :=
+obj-y := reserve_mem-s5pv210.o
obj-m :=
obj-n :=
obj- :=
@@ -15,7 +15,7 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
-obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o dev-cpufreq.o
# machine support
diff --git aosp-v3.0/arch/arm/mach-s5pv210/Makefile.boot smdk4210/arch/arm/mach-s5pv210/Makefile.boot
index ff90aa1..7e1ea1f 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/Makefile.boot
+++ smdk4210/arch/arm/mach-s5pv210/Makefile.boot
@@ -1,2 +1,5 @@
zreladdr-y := 0x20008000
params_phys-y := 0x20000100
+
+ zreladdr-$(CONFIG_CPU_S5PC110) := 0x30008000
+params_phys-$(CONFIG_CPU_S5PC110) := 0x30000100
diff --git aosp-v3.0/arch/arm/mach-s5pv210/clock.c smdk4210/arch/arm/mach-s5pv210/clock.c
index 2d59949..5ea790f 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/clock.c
+++ smdk4210/arch/arm/mach-s5pv210/clock.c
@@ -24,12 +24,14 @@
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h>
+#include <mach/regs-audss.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/pll.h>
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
#include <plat/s5pv210.h>
+#include <plat/devs.h>
static unsigned long xtal;
@@ -185,6 +187,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,
@@ -311,18 +318,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,
@@ -490,6 +485,37 @@ static struct clk init_clocks_off[] = {
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 0),
+ }, {
+ .name = "secss",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = &s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1 << 0),
+ }
+};
+
+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,
},
};
@@ -656,6 +682,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[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &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,
@@ -725,48 +804,13 @@ static struct clksrc_sources clkset_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
};
-static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
-{
- struct clk *pclk;
- int ret;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- ret = pclk->ops->set_rate(pclk, rate);
- clk_put(pclk);
-
- return ret;
-}
-
-static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
-{
- struct clk *pclk;
- int rate;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- rate = pclk->ops->get_rate(clk);
- clk_put(pclk);
-
- return rate;
-}
-
-static struct clk_ops s5pv210_sclk_spdif_ops = {
- .set_rate = s5pv210_spdif_set_rate,
- .get_rate = s5pv210_spdif_get_rate,
-};
-
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 27),
- .ops = &s5pv210_sclk_spdif_ops,
+ .ops = &s5p_sclk_spdif_ops,
},
.sources = &clkset_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
@@ -1062,6 +1106,9 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
+ &clk_mout_audss,
+ &clk_mout_i2s_a,
+ &clk_dout_audio_bus_clk_i2s,
};
static u32 epll_div[][6] = {
@@ -1159,7 +1206,6 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
u32 clkdiv0, clkdiv1;
/* Set functions for clk_fout_epll */
- clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5pv210_epll_ops;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
@@ -1239,5 +1285,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 aosp-v3.0/arch/arm/mach-s5pv210/cpu.c smdk4210/arch/arm/mach-s5pv210/cpu.c
index 61e6c24..d4a8605 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/cpu.c
+++ smdk4210/arch/arm/mach-s5pv210/cpu.c
@@ -38,9 +38,9 @@
#include <plat/ata-core.h>
#include <plat/fimc-core.h>
#include <plat/iic-core.h>
-#include <plat/keypad-core.h>
#include <plat/sdhci.h>
#include <plat/reset.h>
+#include <plat/ace-core.h>
/* Initial IO mappings */
@@ -91,6 +91,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_AUDSS,
+ .pfn = __phys_to_pfn(S5PV210_PA_AUDSS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY,
.pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
.length = SZ_4K,
@@ -126,7 +131,7 @@ void __init s5pv210_map_io(void)
s5pv210_default_sdhci2();
s5pv210_default_sdhci3();
- s3c_adc_setname("s3c64xx-adc");
+ s3c_adc_setname("samsung-adc-v3");
s3c_cfcon_setname("s5pv210-pata");
@@ -141,8 +146,9 @@ void __init s5pv210_map_io(void)
s3c_fb_setname("s5pv210-fb");
- /* Use s5pv210-keypad instead of samsung-keypad */
- samsung_keypad_setname("s5pv210-keypad");
+#ifdef CONFIG_S5P_DEV_ACE
+ s5p_ace_setname("s5pv210-ace");
+#endif
}
void __init s5pv210_init_clocks(int xtal)
diff --git aosp-v3.0/arch/arm/mach-s5pv210/cpufreq.c smdk4210/arch/arm/mach-s5pv210/cpufreq.c
index 153af8b..f18a574 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/cpufreq.c
+++ smdk4210/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,24 @@ static int s5pv210_target(struct cpufreq_policy *policy,
}
}
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
if (freqs.new < freqs.old) {
- /* Voltage down: will be implemented */
+ /* 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);
+ }
}
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
printk(KERN_DEBUG "Perf changed[L%d]\n", index);
- return 0;
+out:
+ mutex_unlock(&set_freq_lock);
+ return ret;
}
#ifdef CONFIG_PM
@@ -464,6 +562,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 +609,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 aosp-v3.0/arch/arm/mach-s5pv210/dev-audio.c smdk4210/arch/arm/mach-s5pv210/dev-audio.c
index 8d58f19..31a965e 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/dev-audio.c
+++ smdk4210/arch/arm/mach-s5pv210/dev-audio.c
@@ -49,8 +49,11 @@ static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pv210_cfg_i2s,
.type = {
.i2s = {
- .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
- | QUIRK_NEED_RSTCLR,
+ .quirks = QUIRK_PRI_6CHAN
+#ifdef CONFIG_SND_SOC_SAMSUNG_I2S_SEC
+ | QUIRK_SEC_DAI
+#endif
+ | QUIRK_NEED_RSTCLR,
.src_clk = rclksrc,
},
},
diff --git aosp-v3.0/arch/arm/mach-s5pv210/dma.c smdk4210/arch/arm/mach-s5pv210/dma.c
index 497d343..34cfacc 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/dma.c
+++ smdk4210/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 aosp-v3.0/arch/arm/mach-s5pv210/include/mach/irqs.h smdk4210/arch/arm/mach-s5pv210/include/mach/irqs.h
index b9f9ec3..1e3ad87 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ smdk4210/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -99,8 +99,8 @@
#define IRQ_TC IRQ_PENDN
#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
#define IRQ_CG S5P_IRQ_VIC2(26)
-#define IRQ_SSS_INT S5P_IRQ_VIC2(27)
-#define IRQ_SSS_HASH S5P_IRQ_VIC2(28)
+#define IRQ_SSS_HASH S5P_IRQ_VIC2(27)
+#define IRQ_SSS_INT S5P_IRQ_VIC2(28)
#define IRQ_PCM2 S5P_IRQ_VIC2(29)
#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
diff --git aosp-v3.0/arch/arm/mach-s5pv210/include/mach/map.h smdk4210/arch/arm/mach-s5pv210/include/mach/map.h
index 1dd5883..4f09492 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/include/mach/map.h
+++ smdk4210/arch/arm/mach-s5pv210/include/mach/map.h
@@ -16,7 +16,11 @@
#include <plat/map-base.h>
#include <plat/map-s5p.h>
+#ifdef CONFIG_CPU_S5PC110
+#define S5PV210_PA_SDRAM 0x30000000
+#else
#define S5PV210_PA_SDRAM 0x20000000
+#endif
#define S5PV210_PA_SROM_BANK5 0xA8000000
@@ -59,11 +63,15 @@
#define S5PV210_PA_CFCON 0xE8200000
+#define S5PV210_PA_ACE 0xEA000000
+
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
#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
@@ -99,8 +107,8 @@
#define S3C_PA_IIC1 S5PV210_PA_IIC1
#define S3C_PA_IIC2 S5PV210_PA_IIC2
#define S3C_PA_RTC S5PV210_PA_RTC
-#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S3C_PA_WDT S5PV210_PA_WATCHDOG
+#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S5P_PA_CHIPID S5PV210_PA_CHIPID
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
@@ -113,11 +121,15 @@
#define S5P_PA_SROMC S5PV210_PA_SROMC
#define S5P_PA_SYSCON S5PV210_PA_SYSCON
#define S5P_PA_TIMER S5PV210_PA_TIMER
+#define S5P_PA_HSOTG S5PV210_PA_HSOTG
+#define S5P_PA_HSPHY S5PV210_PA_HSPHY
#define SAMSUNG_PA_ADC S5PV210_PA_ADC
#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
#define SAMSUNG_PA_KEYPAD S5PV210_PA_KEYPAD
+#define S5P_PA_ACE S5PV210_PA_ACE
+
/* UART */
#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
diff --git aosp-v3.0/arch/arm/mach-s5pv210/include/mach/memory.h smdk4210/arch/arm/mach-s5pv210/include/mach/memory.h
index 7b5fcf0..5c42a7a 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/include/mach/memory.h
+++ smdk4210/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -13,7 +13,11 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
+#ifdef CONFIG_CPU_S5PC110
+#define PLAT_PHYS_OFFSET UL(0x30000000)
+#else
#define PLAT_PHYS_OFFSET UL(0x20000000)
+#endif
#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
/*
diff --git aosp-v3.0/arch/arm/mach-s5pv210/include/mach/pm-core.h smdk4210/arch/arm/mach-s5pv210/include/mach/pm-core.h
index e8d394f..3e22109 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/include/mach/pm-core.h
+++ smdk4210/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -41,3 +41,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
{
/* nothing here yet */
}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void s3c_pm_saved_gpios(void) { }
diff --git aosp-v3.0/arch/arm/mach-s5pv210/include/mach/regs-clock.h smdk4210/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 78925c5..7a843d1 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ smdk4210/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -118,6 +118,32 @@
#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
+/* CLK_OUT register */
+#define S5P_CLKOUT_DIVVAL_SHIFT (20)
+#define S5P_CLKOUT_DIVVAL_MASK (0xF << S5P_CLKOUT_DIVVAL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SHIFT (12)
+#define S5P_CLKOUT_CLKSEL_MASK (0x1F << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_APLL (0 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_MPLL (1 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_EPLL (2 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_VPLL (3 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_USBPHY0 (4 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_USBPHY1 (5 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_HDMIPHY (6 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_RTC (7 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_TICK (8 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK200 (9 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK100 (10 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK166 (11 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK83 (12 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK133 (13 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK66 (14 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_ARMCLK (15 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_HPM (16 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_XXTI (17 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_XUSBXTI (18 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_DOUT (19 << S5P_CLKOUT_CLKSEL_SHIFT)
+
#define S5P_SWRESET S5P_CLKREG(0x2000)
#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
@@ -197,6 +223,11 @@
#define S5P_OTHERS_RET_MMC (1 << 29)
#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
+#define S5P_OTHERS_CLKOUT_SHIFT (8)
+#define S5P_OTHERS_CLKOUT_MASK (0x3 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_SYSCON (0 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_XXIT (2 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_XUSBXTI (3 << S5P_OTHERS_CLKOUT_SHIFT)
/* S5P_DAC_CONTROL */
#define S5P_DAC_ENABLE (1)
diff --git aosp-v3.0/arch/arm/mach-s5pv210/mach-aquila.c smdk4210/arch/arm/mach-s5pv210/mach-aquila.c
index 4e1d8ff..509627f 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/mach-aquila.c
+++ smdk4210/arch/arm/mach-s5pv210/mach-aquila.c
@@ -29,7 +29,6 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
@@ -40,6 +39,7 @@
#include <plat/fimc-core.h>
#include <plat/sdhci.h>
#include <plat/s5p-time.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define AQUILA_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
diff --git aosp-v3.0/arch/arm/mach-s5pv210/mach-goni.c smdk4210/arch/arm/mach-s5pv210/mach-goni.c
index 31d5aa7..e0c4d06 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/mach-goni.c
+++ smdk4210/arch/arm/mach-s5pv210/mach-goni.c
@@ -34,7 +34,6 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
@@ -47,6 +46,7 @@
#include <plat/sdhci.h>
#include <plat/clock.h>
#include <plat/s5p-time.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
diff --git aosp-v3.0/arch/arm/mach-s5pv210/mach-smdkc110.c smdk4210/arch/arm/mach-s5pv210/mach-smdkc110.c
index 6c412c8..85d1b73 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ smdk4210/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -10,27 +10,51 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8698.h>
#include <linux/init.h>
#include <linux/serial_core.h>
-#include <linux/i2c.h>
#include <linux/sysdev.h>
+#include <linux/dm9000.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/delay.h>
+#include <linux/pwm_backlight.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <mach/map.h>
+#include <mach/gpio.h>
#include <mach/regs-clock.h>
+#include <mach/cpu-freq-v210.h>
+#include <mach/media.h>
#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/gpio-cfg.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
#include <plat/ata.h>
#include <plat/iic.h>
+#include <plat/keypad.h>
#include <plat/pm.h>
+#include <plat/fb.h>
#include <plat/s5p-time.h>
+#include <plat/media.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -77,23 +101,511 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+#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
+
+#if defined(CONFIG_REGULATOR_MAX8698)
+/* LDO */
+static struct regulator_consumer_supply smdkc110_ldo3_consumer[] = {
+ REGULATOR_SUPPLY("pd_io", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply smdkc110_ldo5_consumer[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
+};
+
+static struct regulator_consumer_supply smdkc110_ldo8_consumer[] = {
+ REGULATOR_SUPPLY("pd_core", "s3c-usbgadget")
+};
+
+static struct regulator_init_data smdkc110_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo3_data = {
+ .constraints = {
+ .name = "VUOTG_D+VUHOST_D_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(smdkc110_ldo3_consumer),
+ .consumer_supplies = smdkc110_ldo3_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo4_data = {
+ .constraints = {
+ .name = "V_MIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo5_data = {
+ .constraints = {
+ .name = "VMMC+VEXT_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo5_consumer),
+ .consumer_supplies = smdkc110_ldo5_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo6_data = {
+ .constraints = {
+ .name = "VCC_2.6V",
+ .min_uV = 2600000,
+ .max_uV = 2600000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo7_data = {
+ .constraints = {
+ .name = "VDAC_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo8_data = {
+ .constraints = {
+ .name = "VUOTG_A+VUHOST_A_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(smdkc110_ldo8_consumer),
+ .consumer_supplies = smdkc110_ldo8_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo9_data = {
+ .constraints = {
+ .name = "VADC+VSYS+VKEY_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply smdkc110_buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply smdkc110_buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data smdkc110_buck1_data = {
+ .constraints = {
+ .name = "VCC_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 = 1,
+ .consumer_supplies = &smdkc110_buck1_consumer,
+};
+
+static struct regulator_init_data smdkc110_buck2_data = {
+ .constraints = {
+ .name = "VCC_INTERNAL",
+ .min_uV = 950000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkc110_buck2_consumer,
+};
+
+static struct regulator_init_data smdkc110_buck3_data = {
+ .constraints = {
+ .name = "VCC_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .apply_uV = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct max8698_regulator_data smdkc110_regulators[] = {
+ { MAX8698_LDO2, &smdkc110_ldo2_data },
+ { MAX8698_LDO3, &smdkc110_ldo3_data },
+ { MAX8698_LDO4, &smdkc110_ldo4_data },
+ { MAX8698_LDO5, &smdkc110_ldo5_data },
+ { MAX8698_LDO6, &smdkc110_ldo6_data },
+ { MAX8698_LDO7, &smdkc110_ldo7_data },
+ { MAX8698_LDO8, &smdkc110_ldo8_data },
+ { MAX8698_LDO9, &smdkc110_ldo9_data },
+ { MAX8698_BUCK1, &smdkc110_buck1_data },
+ { MAX8698_BUCK2, &smdkc110_buck2_data },
+ { MAX8698_BUCK3, &smdkc110_buck3_data },
+};
+
+static struct max8698_platform_data smdkc110_max8698_pdata = {
+ .num_regulators = ARRAY_SIZE(smdkc110_regulators),
+ .regulators = smdkc110_regulators,
+
+ /* 1GHz default voltage */
+ .dvsarm1 = 0xa, /* 1.25v */
+ .dvsarm2 = 0x9, /* 1.20V */
+ .dvsarm3 = 0x6, /* 1.05V */
+ .dvsarm4 = 0x4, /* 0.95V */
+ .dvsint1 = 0x7, /* 1.10v */
+ .dvsint2 = 0x5, /* 1.00V */
+
+ .set1 = S5PV210_GPH1(6),
+ .set2 = S5PV210_GPH1(7),
+ .set3 = S5PV210_GPH0(4),
+};
+#endif
+
static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
.setup_gpio = s5pv210_ide_setup_gpio,
};
+static uint32_t smdkc110_keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
+ KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
+ KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
+};
+
+static struct matrix_keymap_data smdkc110_keymap_data __initdata = {
+ .keymap = smdkc110_keymap,
+ .keymap_size = ARRAY_SIZE(smdkc110_keymap),
+};
+
+static struct samsung_keypad_platdata smdkc110_keypad_data __initdata = {
+ .keymap_data = &smdkc110_keymap_data,
+ .rows = 2,
+ .cols = 8,
+};
+
+static struct resource smdkc110_dm9000_resources[] = {
+ [0] = {
+ .start = S5PV210_PA_SROM_BANK5,
+ .end = S5PV210_PA_SROM_BANK5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S5PV210_PA_SROM_BANK5 + 2,
+ .end = S5PV210_PA_SROM_BANK5 + 2,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT(9),
+ .end = IRQ_EINT(9),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct dm9000_plat_data smdkc110_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+ .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
+};
+
+struct platform_device smdkc110_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkc110_dm9000_resources),
+ .resource = smdkc110_dm9000_resources,
+ .dev = {
+ .platform_data = &smdkc110_dm9000_platdata,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdkc110_b_pwr_5v_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "PVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data smdkc110_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_b_pwr_5v_consumers),
+ .consumer_supplies = smdkc110_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdkc110_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdkc110_b_pwr_5v_data,
+};
+
+static struct platform_device smdkc110_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdkc110_b_pwr_5v_pdata,
+ },
+};
+#endif
+
+static void smdkc110_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 1);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+
+ /* fire nRESET on power up */
+ gpio_request(S5PV210_GPH0(6), "GPH0");
+
+ gpio_direction_output(S5PV210_GPH0(6), 1);
+
+ gpio_set_value(S5PV210_GPH0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(S5PV210_GPH0(6), 1);
+ mdelay(10);
+
+ gpio_free(S5PV210_GPH0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 0);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc110_lcd_lte480wv_data = {
+ .set_power = smdkc110_lte480wv_set_power,
+};
+
+static struct platform_device smdkc110_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdkc110_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc110_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkc110_lcd0_pdata __initdata = {
+ .win[0] = &smdkc110_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
+static struct gpio_event_direct_entry smdkc110_keypad_key_map[] = {
+ {
+ .gpio = S5PV210_GPH3(7),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdkc110_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdkc110_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdkc110_keypad_key_map)
+};
+
+static struct gpio_event_info *smdkc110_input_info[] = {
+ &smdkc110_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdkc110_input_data = {
+ .names = {
+ "smdkc110-keypad",
+ NULL,
+ },
+ .info = smdkc110_input_info,
+ .info_count = ARRAY_SIZE(smdkc110_input_info),
+};
+
+static struct platform_device smdkc110_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdkc110_input_data,
+ },
+};
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
static struct platform_device *smdkc110_devices[] __initdata = {
- &samsung_asoc_dma,
- &s5pv210_device_iis0,
- &s5pv210_device_ac97,
- &s5pv210_device_spdif,
+ &s3c_device_adc,
&s3c_device_cfcon,
+ &s3c_device_fb,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_i2c2,
&s3c_device_rtc,
+ &s3c_device_ts,
&s3c_device_wdt,
+ &s5pv210_device_ac97,
+ &s5pv210_device_iis0,
+ &s5pv210_device_spdif,
+#ifdef CONFIG_CPU_FREQ
+ &s5pv210_device_cpufreq,
+#endif
+ &samsung_asoc_dma,
+ &samsung_device_keypad,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+ &smdkc110_dm9000,
+ &smdkc110_lcd_lte480wv,
+ &smdkc110_input_device,
+#ifdef CONFIG_REGULATOR
+ &smdkc110_b_pwr_5v,
+#endif
+#ifdef CONFIG_CRYPTO_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
};
+static void __init smdkc110_button_init(void)
+{
+ s3c_gpio_cfgpin(S5PV210_GPH3(7), (0xf << 28));
+ s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), (0xf << 16));
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+}
+
+static void __init smdkc110_dm9000_init(void)
+{
+ unsigned int tmp;
+
+ gpio_request(S5PV210_MP01(5), "nCS5");
+ s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
+ gpio_free(S5PV210_MP01(5));
+
+ tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BC5);
+
+ tmp = __raw_readl(S5P_SROM_BW);
+ tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
+ tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BW);
+}
+
static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
{ I2C_BOARD_INFO("wm8580", 0x1b), },
@@ -104,7 +616,51 @@ static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
};
static struct i2c_board_info smdkc110_i2c_devs2[] __initdata = {
- /* To Be Updated */
+#if defined(CONFIG_REGULATOR_MAX8698)
+ {
+ I2C_BOARD_INFO("max8698", 0xCC >> 1),
+ .platform_data = &smdkc110_max8698_pdata,
+ },
+#endif
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 800,
+ .cal_y_max = 480,
+ .cal_param = {
+ -13357, -85, 53858048, -95, -8493, 32809514, 65536
+ },
+};
+
+static void smdkc110_sound_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~S5P_CLKOUT_CLKSEL_MASK;
+ reg &= ~S5P_CLKOUT_DIVVAL_MASK;
+ reg |= S5P_CLKOUT_CLKSEL_XUSBXTI;
+ reg |= 0x1 << S5P_CLKOUT_DIVVAL_SHIFT;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ reg = __raw_readl(S5P_OTHERS);
+ reg &= ~S5P_OTHERS_CLKOUT_MASK;
+ reg |= S5P_OTHERS_CLKOUT_SYSCON;
+ __raw_writel(reg, S5P_OTHERS);
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkc110_bl_gpio_info = {
+ .no = S5PV210_GPD0(3),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkc110_bl_data = {
+ .pwm_id = 3,
+ .pwm_period_ns = 1000,
};
static void __init smdkc110_map_io(void)
@@ -112,13 +668,21 @@ static void __init smdkc110_map_io(void)
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
- s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+ s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+
+ s5p_reserve_mem(S5P_RANGE_MFC);
}
static void __init smdkc110_machine_init(void)
{
s3c_pm_init();
+ smdkc110_button_init();
+ smdkc110_dm9000_init();
+
+ samsung_keypad_set_platdata(&smdkc110_keypad_data);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL);
@@ -131,6 +695,17 @@ static void __init smdkc110_machine_init(void)
s3c_ide_set_platdata(&smdkc110_ide_pdata);
+ s3c_fb_set_platdata(&smdkc110_lcd0_pdata);
+
+#ifdef CONFIG_CPU_FREQ
+ s5pv210_cpufreq_set_platdata(&smdkc110_cpufreq_plat);
+#endif
+
+ /* SOUND */
+ smdkc110_sound_init();
+
+ samsung_bl_set(&smdkc110_bl_gpio_info, &smdkc110_bl_data);
+
platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s5pv210/mach-smdkv210.c smdk4210/arch/arm/mach-s5pv210/mach-smdkv210.c
index c6a9e86..614ac9a 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ smdk4210/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -11,12 +11,17 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8698.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
#include <linux/dm9000.h>
#include <linux/fb.h>
#include <linux/gpio.h>
+#include <linux/gpio_event.h>
#include <linux/delay.h>
#include <linux/pwm_backlight.h>
@@ -28,8 +33,9 @@
#include <video/platform_lcd.h>
#include <mach/map.h>
+#include <mach/gpio.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
+#include <mach/media.h>
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
@@ -45,6 +51,9 @@
#include <plat/pm.h>
#include <plat/fb.h>
#include <plat/s5p-time.h>
+#include <plat/media.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -91,6 +100,223 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+#if defined(CONFIG_REGULATOR_MAX8698)
+/* LDO */
+static struct regulator_consumer_supply smdkv210_ldo3_consumer[] = {
+ REGULATOR_SUPPLY("pd_io", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply smdkv210_ldo5_consumer[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
+};
+
+static struct regulator_consumer_supply smdkv210_ldo8_consumer[] = {
+ REGULATOR_SUPPLY("pd_core", "s3c-usbgadget")
+};
+
+static struct regulator_init_data smdkv210_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo3_data = {
+ .constraints = {
+ .name = "VUOTG_D+VUHOST_D_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(smdkv210_ldo3_consumer),
+ .consumer_supplies = smdkv210_ldo3_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo4_data = {
+ .constraints = {
+ .name = "V_MIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo5_data = {
+ .constraints = {
+ .name = "VMMC+VEXT_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_ldo5_consumer),
+ .consumer_supplies = smdkv210_ldo5_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo6_data = {
+ .constraints = {
+ .name = "VCC_2.6V",
+ .min_uV = 2600000,
+ .max_uV = 2600000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo7_data = {
+ .constraints = {
+ .name = "VDAC_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo8_data = {
+ .constraints = {
+ .name = "VUOTG_A+VUHOST_A_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(smdkv210_ldo8_consumer),
+ .consumer_supplies = smdkv210_ldo8_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo9_data = {
+ .constraints = {
+ .name = "VADC+VSYS+VKEY_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply smdkv210_buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply smdkv210_buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data smdkv210_buck1_data = {
+ .constraints = {
+ .name = "VCC_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 = 1,
+ .consumer_supplies = &smdkv210_buck1_consumer,
+};
+
+static struct regulator_init_data smdkv210_buck2_data = {
+ .constraints = {
+ .name = "VCC_INTERNAL",
+ .min_uV = 950000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkv210_buck2_consumer,
+};
+
+static struct regulator_init_data smdkv210_buck3_data = {
+ .constraints = {
+ .name = "VCC_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .apply_uV = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct max8698_regulator_data smdkv210_regulators[] = {
+ { MAX8698_LDO2, &smdkv210_ldo2_data },
+ { MAX8698_LDO3, &smdkv210_ldo3_data },
+ { MAX8698_LDO4, &smdkv210_ldo4_data },
+ { MAX8698_LDO5, &smdkv210_ldo5_data },
+ { MAX8698_LDO6, &smdkv210_ldo6_data },
+ { MAX8698_LDO7, &smdkv210_ldo7_data },
+ { MAX8698_LDO8, &smdkv210_ldo8_data },
+ { MAX8698_LDO9, &smdkv210_ldo9_data },
+ { MAX8698_BUCK1, &smdkv210_buck1_data },
+ { MAX8698_BUCK2, &smdkv210_buck2_data },
+ { MAX8698_BUCK3, &smdkv210_buck3_data },
+};
+
+static struct max8698_platform_data smdkv210_max8698_pdata = {
+ .num_regulators = ARRAY_SIZE(smdkv210_regulators),
+ .regulators = smdkv210_regulators,
+
+ /* 1GHz default voltage */
+ .dvsarm1 = 0xa, /* 1.25v */
+ .dvsarm2 = 0x9, /* 1.20V */
+ .dvsarm3 = 0x6, /* 1.05V */
+ .dvsarm4 = 0x4, /* 0.95V */
+ .dvsint1 = 0x7, /* 1.10v */
+ .dvsint2 = 0x5, /* 1.00V */
+
+ .set1 = S5PV210_GPH1(6),
+ .set2 = S5PV210_GPH1(7),
+ .set3 = S5PV210_GPH0(4),
+};
+#endif
+
static struct s3c_ide_platdata smdkv210_ide_pdata __initdata = {
.setup_gpio = s5pv210_ide_setup_gpio,
};
@@ -110,7 +336,7 @@ static struct matrix_keymap_data smdkv210_keymap_data __initdata = {
static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
.keymap_data = &smdkv210_keymap_data,
- .rows = 8,
+ .rows = 2,
.cols = 8,
};
@@ -147,6 +373,38 @@ struct platform_device smdkv210_dm9000 = {
},
};
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdkv210_b_pwr_5v_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "PVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data smdkv210_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_b_pwr_5v_consumers),
+ .consumer_supplies = smdkv210_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdkv210_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdkv210_b_pwr_5v_data,
+};
+
+static struct platform_device smdkv210_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdkv210_b_pwr_5v_pdata,
+ },
+};
+#endif
+
static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
unsigned int power)
{
@@ -210,45 +468,50 @@ static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
.setup_gpio = s5pv210_fb_gpio_setup_24bpp,
};
-static int smdkv210_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5PV210_GPD0(3), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPD for PWM-OUT 3\n");
- return ret;
+static struct gpio_event_direct_entry smdkv210_keypad_key_map[] = {
+ {
+ .gpio = S5PV210_GPH3(7),
+ .code = KEY_POWER,
}
+};
- /* Configure GPIO pin with S5PV210_GPD_0_3_TOUT_3 */
- s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_SFN(2));
-
- return 0;
-}
+static struct gpio_event_input_info smdkv210_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdkv210_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdkv210_keypad_key_map)
+};
-static void smdkv210_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_OUTPUT);
- gpio_free(S5PV210_GPD0(3));
-}
+static struct gpio_event_info *smdkv210_input_info[] = {
+ &smdkv210_keypad_key_info.info,
+};
-static struct platform_pwm_backlight_data smdkv210_backlight_data = {
- .pwm_id = 3,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdkv210_backlight_init,
- .exit = smdkv210_backlight_exit,
+static struct gpio_event_platform_data smdkv210_input_data = {
+ .names = {
+ "smdkv210-keypad",
+ NULL,
+ },
+ .info = smdkv210_input_info,
+ .info_count = ARRAY_SIZE(smdkv210_input_info),
};
-static struct platform_device smdkv210_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[3].dev,
- .platform_data = &smdkv210_backlight_data,
+static struct platform_device smdkv210_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdkv210_input_data,
},
};
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
static struct platform_device *smdkv210_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
@@ -268,12 +531,26 @@ static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_spdif,
&samsung_asoc_dma,
&samsung_device_keypad,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
&smdkv210_dm9000,
&smdkv210_lcd_lte480wv,
- &s3c_device_timer[3],
- &smdkv210_backlight_device,
+ &smdkv210_input_device,
+#ifdef CONFIG_REGULATOR
+ &smdkv210_b_pwr_5v,
+#endif
};
+static void __init smdkv210_button_init(void)
+{
+ s3c_gpio_cfgpin(S5PV210_GPH3(7), (0xf << 28));
+ s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), (0xf << 16));
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+}
+
static void __init smdkv210_dm9000_init(void)
{
unsigned int tmp;
@@ -301,13 +578,51 @@ static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
};
static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
- /* To Be Updated */
+#if defined(CONFIG_REGULATOR_MAX8698)
+ {
+ I2C_BOARD_INFO("max8698", 0xCC >> 1),
+ .platform_data = &smdkv210_max8698_pdata,
+ },
+#endif
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
+ .cal_x_max = 800,
+ .cal_y_max = 480,
+ .cal_param = {
+ -13357, -85, 53858048, -95, -8493, 32809514, 65536
+ },
+};
+
+static void smdkv210_sound_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~S5P_CLKOUT_CLKSEL_MASK;
+ reg &= ~S5P_CLKOUT_DIVVAL_MASK;
+ reg |= S5P_CLKOUT_CLKSEL_XUSBXTI;
+ reg |= 0x1 << S5P_CLKOUT_DIVVAL_SHIFT;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ reg = __raw_readl(S5P_OTHERS);
+ reg &= ~S5P_OTHERS_CLKOUT_MASK;
+ reg |= S5P_OTHERS_CLKOUT_SYSCON;
+ __raw_writel(reg, S5P_OTHERS);
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkv210_bl_gpio_info = {
+ .no = S5PV210_GPD0(3),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkv210_bl_data = {
+ .pwm_id = 3,
+ .pwm_period_ns = 1000,
};
static void __init smdkv210_map_io(void)
@@ -316,12 +631,15 @@ static void __init smdkv210_map_io(void)
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+
+ s5p_reserve_mem(S5P_RANGE_MFC);
}
static void __init smdkv210_machine_init(void)
{
s3c_pm_init();
+ smdkv210_button_init();
smdkv210_dm9000_init();
samsung_keypad_set_platdata(&smdkv210_keypad_data);
@@ -341,6 +659,11 @@ static void __init smdkv210_machine_init(void)
s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
+ /* SOUND */
+ smdkv210_sound_init();
+
+ samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
+
platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
}
diff --git aosp-v3.0/arch/arm/mach-s5pv210/setup-fb-24bpp.c smdk4210/arch/arm/mach-s5pv210/setup-fb-24bpp.c
index e932ebf..55103c8 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/setup-fb-24bpp.c
+++ smdk4210/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -15,7 +15,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <plat/fb.h>
#include <mach/regs-clock.h>
diff --git aosp-v3.0/arch/arm/mach-s5pv210/setup-keypad.c smdk4210/arch/arm/mach-s5pv210/setup-keypad.c
index c56420a..d631917 100644
--- aosp-v3.0/arch/arm/mach-s5pv210/setup-keypad.c
+++ smdk4210/arch/arm/mach-s5pv210/setup-keypad.c
@@ -17,7 +17,8 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
- s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
+ s3c_gpio_cfgall_range(S5PV210_GPH3(0), rows,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
diff --git aosp-v3.0/arch/arm/mm/Kconfig smdk4210/arch/arm/mm/Kconfig
index 0074b8d..cbab5c5 100644
--- aosp-v3.0/arch/arm/mm/Kconfig
+++ smdk4210/arch/arm/mm/Kconfig
@@ -629,6 +629,16 @@ config IO_36
comment "Processor Features"
+config ARM_TRUSTZONE
+ bool "Support TrustZone-enabled Trusted Execution Environment"
+ default n
+ help
+ Select if you want a kernel to be executed at non-secure world.
+ This option should be used with related secure bootloader and
+ TrustZone software.
+
+ If you don't know about TrustZone, say 'N'.
+
config ARM_THUMB
bool "Support Thumb user binaries"
depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
diff --git aosp-v3.0/arch/arm/mm/Makefile smdk4210/arch/arm/mm/Makefile
index bca7e61..b44e104 100644
--- aosp-v3.0/arch/arm/mm/Makefile
+++ smdk4210/arch/arm/mm/Makefile
@@ -2,11 +2,33 @@
# Makefile for the linux arm-specific parts of the memory manager.
#
-obj-y := dma-mapping.o extable.o fault.o init.o \
+obj-y := extable.o fault.o \
iomap.o
+ifeq ($(CONFIG_SLP),y)
+obj-y += dma-mapping-slp.o init-slp.o
+else
+ifeq ($(CONFIG_DMA_CMA),y)
+obj-y += dma-mapping-cma.o init-cma.o
+else
+obj-y += dma-mapping.o init.o
+endif
+endif
+
obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
- mmap.o pgd.o mmu.o vmregion.o
+ mmap.o pgd.o vmregion.o
+
+ifeq ($(CONFIG_MMU),y)
+ifeq ($(CONFIG_SLP),y)
+obj-y += mmu-slp.o
+else
+ifeq ($(CONFIG_DMA_CMA),y)
+obj-y += mmu-cma.o
+else
+obj-y += mmu.o
+endif
+endif
+endif
ifneq ($(CONFIG_MMU),y)
obj-y += nommu.o
@@ -100,3 +122,4 @@ obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o
+obj-$(CONFIG_CACHE_PERF) += cache_perf.o
diff --git aosp-v3.0/arch/arm/mm/alignment.c smdk4210/arch/arm/mm/alignment.c
index 724ba3b..900e647 100644
--- aosp-v3.0/arch/arm/mm/alignment.c
+++ smdk4210/arch/arm/mm/alignment.c
@@ -914,7 +914,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
*/
static int __init alignment_init(void)
{
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_PROC_FS) && !defined(CONFIG_FAST_RESUME)
struct proc_dir_entry *res;
res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
@@ -956,5 +956,8 @@ static int __init alignment_init(void)
return 0;
}
-
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(alignment_init);
+#else
fs_initcall(alignment_init);
+#endif
diff --git aosp-v3.0/arch/arm/mm/cache-fa.S smdk4210/arch/arm/mm/cache-fa.S
index 1fa6f71..0720163 100644
--- aosp-v3.0/arch/arm/mm/cache-fa.S
+++ smdk4210/arch/arm/mm/cache-fa.S
@@ -242,16 +242,5 @@ ENDPROC(fa_dma_unmap_area)
__INITDATA
- .type fa_cache_fns, #object
-ENTRY(fa_cache_fns)
- .long fa_flush_icache_all
- .long fa_flush_kern_cache_all
- .long fa_flush_user_cache_all
- .long fa_flush_user_cache_range
- .long fa_coherent_kern_range
- .long fa_coherent_user_range
- .long fa_flush_kern_dcache_area
- .long fa_dma_map_area
- .long fa_dma_unmap_area
- .long fa_dma_flush_range
- .size fa_cache_fns, . - fa_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions fa
diff --git aosp-v3.0/arch/arm/mm/cache-l2x0.c smdk4210/arch/arm/mm/cache-l2x0.c
index 6f6c1a6..68052e6 100644
--- aosp-v3.0/arch/arm/mm/cache-l2x0.c
+++ smdk4210/arch/arm/mm/cache-l2x0.c
@@ -386,6 +386,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.sync = l2x0_cache_sync;
outer_cache.flush_all = l2x0_flush_all;
outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.clean_all = l2x0_clean_all;
outer_cache.disable = l2x0_disable;
outer_cache.set_debug = l2x0_set_debug;
diff --git aosp-v3.0/arch/arm/mm/cache-v3.S smdk4210/arch/arm/mm/cache-v3.S
index 2e2bc40..c2301f2 100644
--- aosp-v3.0/arch/arm/mm/cache-v3.S
+++ smdk4210/arch/arm/mm/cache-v3.S
@@ -129,16 +129,5 @@ ENDPROC(v3_dma_map_area)
__INITDATA
- .type v3_cache_fns, #object
-ENTRY(v3_cache_fns)
- .long v3_flush_icache_all
- .long v3_flush_kern_cache_all
- .long v3_flush_user_cache_all
- .long v3_flush_user_cache_range
- .long v3_coherent_kern_range
- .long v3_coherent_user_range
- .long v3_flush_kern_dcache_area
- .long v3_dma_map_area
- .long v3_dma_unmap_area
- .long v3_dma_flush_range
- .size v3_cache_fns, . - v3_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v3
diff --git aosp-v3.0/arch/arm/mm/cache-v4.S smdk4210/arch/arm/mm/cache-v4.S
index a8fefb5..fd9bb7a 100644
--- aosp-v3.0/arch/arm/mm/cache-v4.S
+++ smdk4210/arch/arm/mm/cache-v4.S
@@ -141,16 +141,5 @@ ENDPROC(v4_dma_map_area)
__INITDATA
- .type v4_cache_fns, #object
-ENTRY(v4_cache_fns)
- .long v4_flush_icache_all
- .long v4_flush_kern_cache_all
- .long v4_flush_user_cache_all
- .long v4_flush_user_cache_range
- .long v4_coherent_kern_range
- .long v4_coherent_user_range
- .long v4_flush_kern_dcache_area
- .long v4_dma_map_area
- .long v4_dma_unmap_area
- .long v4_dma_flush_range
- .size v4_cache_fns, . - v4_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4
diff --git aosp-v3.0/arch/arm/mm/cache-v4wb.S smdk4210/arch/arm/mm/cache-v4wb.S
index f40c696..4f2c141 100644
--- aosp-v3.0/arch/arm/mm/cache-v4wb.S
+++ smdk4210/arch/arm/mm/cache-v4wb.S
@@ -253,16 +253,5 @@ ENDPROC(v4wb_dma_unmap_area)
__INITDATA
- .type v4wb_cache_fns, #object
-ENTRY(v4wb_cache_fns)
- .long v4wb_flush_icache_all
- .long v4wb_flush_kern_cache_all
- .long v4wb_flush_user_cache_all
- .long v4wb_flush_user_cache_range
- .long v4wb_coherent_kern_range
- .long v4wb_coherent_user_range
- .long v4wb_flush_kern_dcache_area
- .long v4wb_dma_map_area
- .long v4wb_dma_unmap_area
- .long v4wb_dma_flush_range
- .size v4wb_cache_fns, . - v4wb_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wb
diff --git aosp-v3.0/arch/arm/mm/cache-v4wt.S smdk4210/arch/arm/mm/cache-v4wt.S
index a7b276d..4d7b467 100644
--- aosp-v3.0/arch/arm/mm/cache-v4wt.S
+++ smdk4210/arch/arm/mm/cache-v4wt.S
@@ -197,16 +197,5 @@ ENDPROC(v4wt_dma_map_area)
__INITDATA
- .type v4wt_cache_fns, #object
-ENTRY(v4wt_cache_fns)
- .long v4wt_flush_icache_all
- .long v4wt_flush_kern_cache_all
- .long v4wt_flush_user_cache_all
- .long v4wt_flush_user_cache_range
- .long v4wt_coherent_kern_range
- .long v4wt_coherent_user_range
- .long v4wt_flush_kern_dcache_area
- .long v4wt_dma_map_area
- .long v4wt_dma_unmap_area
- .long v4wt_dma_flush_range
- .size v4wt_cache_fns, . - v4wt_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wt
diff --git aosp-v3.0/arch/arm/mm/cache-v6.S smdk4210/arch/arm/mm/cache-v6.S
index 6b5441d..2edb6f6 100644
--- aosp-v3.0/arch/arm/mm/cache-v6.S
+++ smdk4210/arch/arm/mm/cache-v6.S
@@ -347,16 +347,5 @@ ENDPROC(v6_dma_unmap_area)
__INITDATA
- .type v6_cache_fns, #object
-ENTRY(v6_cache_fns)
- .long v6_flush_icache_all
- .long v6_flush_kern_cache_all
- .long v6_flush_user_cache_all
- .long v6_flush_user_cache_range
- .long v6_coherent_kern_range
- .long v6_coherent_user_range
- .long v6_flush_kern_dcache_area
- .long v6_dma_map_area
- .long v6_dma_unmap_area
- .long v6_dma_flush_range
- .size v6_cache_fns, . - v6_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v6
diff --git aosp-v3.0/arch/arm/mm/cache-v7.S smdk4210/arch/arm/mm/cache-v7.S
index 1ed1fd3..a655d3d 100644
--- aosp-v3.0/arch/arm/mm/cache-v7.S
+++ smdk4210/arch/arm/mm/cache-v7.S
@@ -351,16 +351,5 @@ ENDPROC(v7_dma_unmap_area)
__INITDATA
- .type v7_cache_fns, #object
-ENTRY(v7_cache_fns)
- .long v7_flush_icache_all
- .long v7_flush_kern_cache_all
- .long v7_flush_user_cache_all
- .long v7_flush_user_cache_range
- .long v7_coherent_kern_range
- .long v7_coherent_user_range
- .long v7_flush_kern_dcache_area
- .long v7_dma_map_area
- .long v7_dma_unmap_area
- .long v7_dma_flush_range
- .size v7_cache_fns, . - v7_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v7
diff --git aosp-v3.0/arch/arm/mm/fault.c smdk4210/arch/arm/mm/fault.c
index bc0e1d8..6f66c0e 100644
--- aosp-v3.0/arch/arm/mm/fault.c
+++ smdk4210/arch/arm/mm/fault.c
@@ -24,6 +24,10 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+#if defined(CONFIG_MACH_Q1_BD)
+#include <mach/sec_debug.h>
+#endif
+
#include "fault.h"
/*
@@ -162,6 +166,29 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
do_exit(SIGKILL);
}
+#if defined(CONFIG_MACH_Q1_BD)
+/*
+ * This function can be used while current pointer is invalid.
+ */
+static void
+__do_kernel_fault_safe(struct mm_struct *mm, unsigned long addr,
+ unsigned int fsr, struct pt_regs *regs)
+{
+ static char buf[64] = "__do_kernel_fault_safe";
+
+ printk(KERN_ALERT
+ "Unable to handle kernel %s at virtual address %08lx\n",
+ (addr < PAGE_SIZE) ? "NULL pointer dereference" :
+ "paging request", addr);
+
+ printk(KERN_ALERT "current is %p\n", current);
+
+ __show_regs(regs);
+
+ sec_debug_panic_handler_safe(buf);
+}
+#endif
+
/*
* Something tried to access memory that isn't in our memory map..
* User mode accesses just cause a SIGSEGV
@@ -283,7 +310,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
return 0;
tsk = current;
- mm = tsk->mm;
+#if defined(CONFIG_MACH_Q1_BD)
+ /*
+ * If current pointer is NULL, infinite abort can occur.
+ * It make us get correct debug information in the situation.
+ */
+ if (!tsk) {
+ __do_kernel_fault_safe(NULL, addr, fsr, regs);
+ return 0;
+ }
+#endif
+ mm = tsk->mm;
/*
* If we're in an interrupt or have no user
diff --git aosp-v3.0/arch/arm/mm/ioremap.c smdk4210/arch/arm/mm/ioremap.c
index ab50627..42f099e 100644
--- aosp-v3.0/arch/arm/mm/ioremap.c
+++ smdk4210/arch/arm/mm/ioremap.c
@@ -22,6 +22,7 @@
*/
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
@@ -204,7 +205,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
- if (WARN_ON(pfn_valid(pfn)))
+ if (WARN_ON(memblock_is_memory(pfn << PAGE_SHIFT)))
return NULL;
type = get_mem_type(mtype);
diff --git aosp-v3.0/arch/arm/mm/mm.h smdk4210/arch/arm/mm/mm.h
index 5b3d7d5..7f2b1f6 100644
--- aosp-v3.0/arch/arm/mm/mm.h
+++ smdk4210/arch/arm/mm/mm.h
@@ -23,5 +23,19 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#endif
+#ifdef CONFIG_ZONE_DMA
+extern phys_addr_t arm_dma_limit;
+#else
+#define arm_dma_limit ((u32)~0)
+#endif
+
+#ifdef CONFIG_DMA_CMA
+extern phys_addr_t arm_lowmem_limit;
+#endif
+
void __init bootmem_init(void);
void arm_mm_memblock_reserve(void);
+#ifdef CONFIG_DMA_CMA
+void dma_contiguous_remap(void);
+#endif
+
diff --git aosp-v3.0/arch/arm/mm/proc-arm1020.S smdk4210/arch/arm/mm/proc-arm1020.S
index 6c4e7fd..6746966 100644
--- aosp-v3.0/arch/arm/mm/proc-arm1020.S
+++ smdk4210/arch/arm/mm/proc-arm1020.S
@@ -364,17 +364,8 @@ ENTRY(arm1020_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020_dma_unmap_area)
-ENTRY(arm1020_cache_fns)
- .long arm1020_flush_icache_all
- .long arm1020_flush_kern_cache_all
- .long arm1020_flush_user_cache_all
- .long arm1020_flush_user_cache_range
- .long arm1020_coherent_kern_range
- .long arm1020_coherent_user_range
- .long arm1020_flush_kern_dcache_area
- .long arm1020_dma_map_area
- .long arm1020_dma_unmap_area
- .long arm1020_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020
.align 5
ENTRY(cpu_arm1020_dcache_clean_area)
@@ -477,38 +468,14 @@ arm1020_crval:
crval clear=0x0000593f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020, dabort=v4t_early_abort, pabort=legacy_pabort
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1020_processor_functions, #object
-arm1020_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1020_proc_init
- .word cpu_arm1020_proc_fin
- .word cpu_arm1020_reset
- .word cpu_arm1020_do_idle
- .word cpu_arm1020_dcache_clean_area
- .word cpu_arm1020_switch_mm
- .word cpu_arm1020_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv5t"
+ string cpu_elf_name, "v5"
.type cpu_arm1020_name, #object
cpu_arm1020_name:
diff --git aosp-v3.0/arch/arm/mm/proc-arm1020e.S smdk4210/arch/arm/mm/proc-arm1020e.S
index 4ce947c..4251421 100644
--- aosp-v3.0/arch/arm/mm/proc-arm1020e.S
+++ smdk4210/arch/arm/mm/proc-arm1020e.S
@@ -350,17 +350,8 @@ ENTRY(arm1020e_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020e_dma_unmap_area)
-ENTRY(arm1020e_cache_fns)
- .long arm1020e_flush_icache_all
- .long arm1020e_flush_kern_cache_all
- .long arm1020e_flush_user_cache_all
- .long arm1020e_flush_user_cache_range
- .long arm1020e_coherent_kern_range
- .long arm1020e_coherent_user_range
- .long arm1020e_flush_kern_dcache_area
- .long arm1020e_dma_map_area
- .long arm1020e_dma_unmap_area
- .long arm1020e_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020e
.align 5
ENTRY(cpu_arm1020e_dcache_clean_area)
@@ -458,43 +449,14 @@ arm1020e_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1020e_processor_functions, #object
-arm1020e_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1020e_proc_init
- .word cpu_arm1020e_proc_fin
- .word cpu_arm1020e_reset
- .word cpu_arm1020e_do_idle
- .word cpu_arm1020e_dcache_clean_area
- .word cpu_arm1020e_switch_mm
- .word cpu_arm1020e_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1020e_processor_functions, . - arm1020e_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020e, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm1020e_name, #object
-cpu_arm1020e_name:
- .asciz "ARM1020E"
- .size cpu_arm1020e_name, . - cpu_arm1020e_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1020e_name, "ARM1020E"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm1022.S smdk4210/arch/arm/mm/proc-arm1022.S
index c8884c5..d283cf3 100644
--- aosp-v3.0/arch/arm/mm/proc-arm1022.S
+++ smdk4210/arch/arm/mm/proc-arm1022.S
@@ -339,17 +339,8 @@ ENTRY(arm1022_dma_unmap_area)
mov pc, lr
ENDPROC(arm1022_dma_unmap_area)
-ENTRY(arm1022_cache_fns)
- .long arm1022_flush_icache_all
- .long arm1022_flush_kern_cache_all
- .long arm1022_flush_user_cache_all
- .long arm1022_flush_user_cache_range
- .long arm1022_coherent_kern_range
- .long arm1022_coherent_user_range
- .long arm1022_flush_kern_dcache_area
- .long arm1022_dma_map_area
- .long arm1022_dma_unmap_area
- .long arm1022_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1022
.align 5
ENTRY(cpu_arm1022_dcache_clean_area)
@@ -441,43 +432,14 @@ arm1022_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1022_processor_functions, #object
-arm1022_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1022_proc_init
- .word cpu_arm1022_proc_fin
- .word cpu_arm1022_reset
- .word cpu_arm1022_do_idle
- .word cpu_arm1022_dcache_clean_area
- .word cpu_arm1022_switch_mm
- .word cpu_arm1022_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1022_processor_functions, . - arm1022_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1022, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm1022_name, #object
-cpu_arm1022_name:
- .asciz "ARM1022"
- .size cpu_arm1022_name, . - cpu_arm1022_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1022_name, "ARM1022"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm1026.S smdk4210/arch/arm/mm/proc-arm1026.S
index 4136846..678a1ce 100644
--- aosp-v3.0/arch/arm/mm/proc-arm1026.S
+++ smdk4210/arch/arm/mm/proc-arm1026.S
@@ -333,17 +333,8 @@ ENTRY(arm1026_dma_unmap_area)
mov pc, lr
ENDPROC(arm1026_dma_unmap_area)
-ENTRY(arm1026_cache_fns)
- .long arm1026_flush_icache_all
- .long arm1026_flush_kern_cache_all
- .long arm1026_flush_user_cache_all
- .long arm1026_flush_user_cache_range
- .long arm1026_coherent_kern_range
- .long arm1026_coherent_user_range
- .long arm1026_flush_kern_dcache_area
- .long arm1026_dma_map_area
- .long arm1026_dma_unmap_area
- .long arm1026_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1026
.align 5
ENTRY(cpu_arm1026_dcache_clean_area)
@@ -436,45 +427,15 @@ arm1026_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1026_processor_functions, #object
-arm1026_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_arm1026_proc_init
- .word cpu_arm1026_proc_fin
- .word cpu_arm1026_reset
- .word cpu_arm1026_do_idle
- .word cpu_arm1026_dcache_clean_area
- .word cpu_arm1026_switch_mm
- .word cpu_arm1026_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1026_processor_functions, . - arm1026_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort
.section .rodata
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5tej"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
.align
-
- .type cpu_arm1026_name, #object
-cpu_arm1026_name:
- .asciz "ARM1026EJ-S"
- .size cpu_arm1026_name, . - cpu_arm1026_name
-
+ string cpu_arm1026_name, "ARM1026EJ-S"
.align
.section ".proc.info.init", #alloc, #execinstr
diff --git aosp-v3.0/arch/arm/mm/proc-arm6_7.S smdk4210/arch/arm/mm/proc-arm6_7.S
index 5f79dc4..ebc0ca7 100644
--- aosp-v3.0/arch/arm/mm/proc-arm6_7.S
+++ smdk4210/arch/arm/mm/proc-arm6_7.S
@@ -269,159 +269,57 @@ __arm7_setup: mov r0, #0
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm6_processor_functions, #object
-ENTRY(arm6_processor_functions)
- .word cpu_arm6_data_abort
- .word legacy_pabort
- .word cpu_arm6_proc_init
- .word cpu_arm6_proc_fin
- .word cpu_arm6_reset
- .word cpu_arm6_do_idle
- .word cpu_arm6_dcache_clean_area
- .word cpu_arm6_switch_mm
- .word cpu_arm6_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm6_processor_functions, . - arm6_processor_functions
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm7_processor_functions, #object
-ENTRY(arm7_processor_functions)
- .word cpu_arm7_data_abort
- .word legacy_pabort
- .word cpu_arm7_proc_init
- .word cpu_arm7_proc_fin
- .word cpu_arm7_reset
- .word cpu_arm7_do_idle
- .word cpu_arm7_dcache_clean_area
- .word cpu_arm7_switch_mm
- .word cpu_arm7_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm7_processor_functions, . - arm7_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm6, dabort=cpu_arm6_data_abort, pabort=legacy_pabort
+ define_processor_functions arm7, dabort=cpu_arm7_data_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv3"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v3"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm6_name, #object
-cpu_arm6_name: .asciz "ARM6"
- .size cpu_arm6_name, . - cpu_arm6_name
-
- .type cpu_arm610_name, #object
-cpu_arm610_name:
- .asciz "ARM610"
- .size cpu_arm610_name, . - cpu_arm610_name
-
- .type cpu_arm7_name, #object
-cpu_arm7_name: .asciz "ARM7"
- .size cpu_arm7_name, . - cpu_arm7_name
-
- .type cpu_arm710_name, #object
-cpu_arm710_name:
- .asciz "ARM710"
- .size cpu_arm710_name, . - cpu_arm710_name
+ string cpu_arch_name, "armv3"
+ string cpu_elf_name, "v3"
+ string cpu_arm6_name, "ARM6"
+ string cpu_arm610_name, "ARM610"
+ string cpu_arm7_name, "ARM7"
+ string cpu_arm710_name, "ARM710"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm6_proc_info, #object
-__arm6_proc_info:
- .long 0x41560600
- .long 0xfffffff0
- .long 0x00000c1e
+.macro arm67_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ cpu_mm_mmu_flags:req, cpu_flush:req, cpu_proc_funcs:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long \cpu_mm_mmu_flags
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __arm6_setup
+ b \cpu_flush
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm6_name
- .long arm6_processor_functions
+ .long \cpu_name
+ .long \cpu_proc_funcs
.long v3_tlb_fns
.long v3_user_fns
.long v3_cache_fns
- .size __arm6_proc_info, . - __arm6_proc_info
-
- .type __arm610_proc_info, #object
-__arm610_proc_info:
- .long 0x41560610
- .long 0xfffffff0
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm6_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm610_name
- .long arm6_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm610_proc_info, . - __arm610_proc_info
-
- .type __arm7_proc_info, #object
-__arm7_proc_info:
- .long 0x41007000
- .long 0xffffff00
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm7_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm7_proc_info, . - __arm7_proc_info
-
- .type __arm710_proc_info, #object
-__arm710_proc_info:
- .long 0x41007100
- .long 0xfff8ff00
- .long PMD_TYPE_SECT | \
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm67_proc_info arm6, 0x41560600, 0xfffffff0, cpu_arm6_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm610, 0x41560610, 0xfffffff0, cpu_arm610_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm7, 0x41007000, 0xffffff00, cpu_arm7_name, \
+ 0x00000c1e, __arm7_setup, arm7_processor_functions
+ arm67_proc_info arm710, 0x41007100, 0xfff8ff00, cpu_arm710_name, \
+ PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm710_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm710_proc_info, . - __arm710_proc_info
+ PMD_SECT_AP_READ, \
+ __arm7_setup, arm7_processor_functions
diff --git aosp-v3.0/arch/arm/mm/proc-arm720.S smdk4210/arch/arm/mm/proc-arm720.S
index 7a06e59..55f4e29 100644
--- aosp-v3.0/arch/arm/mm/proc-arm720.S
+++ smdk4210/arch/arm/mm/proc-arm720.S
@@ -169,46 +169,15 @@ arm720_crval:
crval clear=0x00002f3f, mmuset=0x0000213d, ucset=0x00000130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm720_processor_functions, #object
-ENTRY(arm720_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm720_proc_init
- .word cpu_arm720_proc_fin
- .word cpu_arm720_reset
- .word cpu_arm720_do_idle
- .word cpu_arm720_dcache_clean_area
- .word cpu_arm720_switch_mm
- .word cpu_arm720_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm720_processor_functions, . - arm720_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm720, dabort=v4t_late_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm710_name, #object
-cpu_arm710_name:
- .asciz "ARM710T"
- .size cpu_arm710_name, . - cpu_arm710_name
-
- .type cpu_arm720_name, #object
-cpu_arm720_name:
- .asciz "ARM720T"
- .size cpu_arm720_name, . - cpu_arm720_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm710_name, "ARM710T"
+ string cpu_arm720_name, "ARM720T"
.align
@@ -218,10 +187,11 @@ cpu_arm720_name:
.section ".proc.info.init", #alloc, #execinstr
- .type __arm710_proc_info, #object
-__arm710_proc_info:
- .long 0x41807100 @ cpu_val
- .long 0xffffff00 @ cpu_mask
+.macro arm720_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cpu_flush:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -232,38 +202,17 @@ __arm710_proc_info:
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __arm710_setup @ cpu_flush
+ b \cpu_flush @ cpu_flush
.long cpu_arch_name @ arch_name
.long cpu_elf_name @ elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap
- .long cpu_arm710_name @ name
+ .long \cpu_name
.long arm720_processor_functions
.long v4_tlb_fns
.long v4wt_user_fns
.long v4_cache_fns
- .size __arm710_proc_info, . - __arm710_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __arm720_proc_info, #object
-__arm720_proc_info:
- .long 0x41807200 @ cpu_val
- .long 0xffffff00 @ cpu_mask
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm720_setup @ cpu_flush
- .long cpu_arch_name @ arch_name
- .long cpu_elf_name @ elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap
- .long cpu_arm720_name @ name
- .long arm720_processor_functions
- .long v4_tlb_fns
- .long v4wt_user_fns
- .long v4_cache_fns
- .size __arm720_proc_info, . - __arm720_proc_info
+ arm720_proc_info arm710, 0x41807100, 0xffffff00, cpu_arm710_name, __arm710_setup
+ arm720_proc_info arm720, 0x41807200, 0xffffff00, cpu_arm720_name, __arm720_setup
diff --git aosp-v3.0/arch/arm/mm/proc-arm740.S smdk4210/arch/arm/mm/proc-arm740.S
index 6f9d12e..4506be3 100644
--- aosp-v3.0/arch/arm/mm/proc-arm740.S
+++ smdk4210/arch/arm/mm/proc-arm740.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm740_proc_init()
@@ -115,42 +117,14 @@ __arm740_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm740_processor_functions, #object
-ENTRY(arm740_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm740_proc_init
- .word cpu_arm740_proc_fin
- .word cpu_arm740_reset
- .word cpu_arm740_do_idle
- .word cpu_arm740_dcache_clean_area
- .word cpu_arm740_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm740_processor_functions, . - arm740_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm740, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm740_name, #object
-cpu_arm740_name:
- .ascii "ARM740T"
- .size cpu_arm740_name, . - cpu_arm740_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_arm740_name, "ARM740T"
.align
@@ -170,5 +144,3 @@ __arm740_proc_info:
.long 0
.long v3_cache_fns @ cache model
.size __arm740_proc_info, . - __arm740_proc_info
-
-
diff --git aosp-v3.0/arch/arm/mm/proc-arm7tdmi.S smdk4210/arch/arm/mm/proc-arm7tdmi.S
index 537ffcb..7e0e1fe 100644
--- aosp-v3.0/arch/arm/mm/proc-arm7tdmi.S
+++ smdk4210/arch/arm/mm/proc-arm7tdmi.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm7tdmi_proc_init()
@@ -55,197 +57,57 @@ __arm7tdmi_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm7tdmi_processor_functions, #object
-ENTRY(arm7tdmi_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm7tdmi_proc_init
- .word cpu_arm7tdmi_proc_fin
- .word cpu_arm7tdmi_reset
- .word cpu_arm7tdmi_do_idle
- .word cpu_arm7tdmi_dcache_clean_area
- .word cpu_arm7tdmi_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm7tdmi, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm7tdmi_name, #object
-cpu_arm7tdmi_name:
- .asciz "ARM7TDMI"
- .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name
-
- .type cpu_triscenda7_name, #object
-cpu_triscenda7_name:
- .asciz "Triscend-A7x"
- .size cpu_triscenda7_name, . - cpu_triscenda7_name
-
- .type cpu_at91_name, #object
-cpu_at91_name:
- .asciz "Atmel-AT91M40xxx"
- .size cpu_at91_name, . - cpu_at91_name
-
- .type cpu_s3c3410_name, #object
-cpu_s3c3410_name:
- .asciz "Samsung-S3C3410"
- .size cpu_s3c3410_name, . - cpu_s3c3410_name
-
- .type cpu_s3c44b0x_name, #object
-cpu_s3c44b0x_name:
- .asciz "Samsung-S3C44B0x"
- .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name
-
- .type cpu_s3c4510b, #object
-cpu_s3c4510b_name:
- .asciz "Samsung-S3C4510B"
- .size cpu_s3c4510b_name, . - cpu_s3c4510b_name
-
- .type cpu_s3c4530_name, #object
-cpu_s3c4530_name:
- .asciz "Samsung-S3C4530"
- .size cpu_s3c4530_name, . - cpu_s3c4530_name
-
- .type cpu_netarm_name, #object
-cpu_netarm_name:
- .asciz "NETARM"
- .size cpu_netarm_name, . - cpu_netarm_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm7tdmi_name, "ARM7TDMI"
+ string cpu_triscenda7_name, "Triscend-A7x"
+ string cpu_at91_name, "Atmel-AT91M40xxx"
+ string cpu_s3c3410_name, "Samsung-S3C3410"
+ string cpu_s3c44b0x_name, "Samsung-S3C44B0x"
+ string cpu_s3c4510b_name, "Samsung-S3C4510B"
+ string cpu_s3c4530_name, "Samsung-S3C4530"
+ string cpu_netarm_name, "NETARM"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm7tdmi_proc_info, #object
-__arm7tdmi_proc_info:
- .long 0x41007700
- .long 0xfff8ff00
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm7tdmi_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __arm7tdmi_proc_info, . - __arm7tdmi_proc_info
-
- .type __triscenda7_proc_info, #object
-__triscenda7_proc_info:
- .long 0x0001d2ff
- .long 0x0001ffff
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_triscenda7_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __triscenda7_proc_info, . - __triscenda7_proc_info
-
- .type __at91_proc_info, #object
-__at91_proc_info:
- .long 0x14000040
- .long 0xfff000e0
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_at91_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __at91_proc_info, . - __at91_proc_info
-
- .type __s3c4510b_proc_info, #object
-__s3c4510b_proc_info:
- .long 0x36365000
- .long 0xfffff000
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c4510b_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c4510b_proc_info, . - __s3c4510b_proc_info
-
- .type __s3c4530_proc_info, #object
-__s3c4530_proc_info:
- .long 0x4c000000
- .long 0xfff000e0
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c4530_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c4530_proc_info, . - __s3c4530_proc_info
-
- .type __s3c3410_proc_info, #object
-__s3c3410_proc_info:
- .long 0x34100000
- .long 0xffff0000
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c3410_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c3410_proc_info, . - __s3c3410_proc_info
-
- .type __s3c44b0x_proc_info, #object
-__s3c44b0x_proc_info:
- .long 0x44b00000
- .long 0xffff0000
+.macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ extra_hwcaps=0
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long 0
.long 0
b __arm7tdmi_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c44b0x_name
+ .long HWCAP_SWP | HWCAP_26BIT | ( \extra_hwcaps )
+ .long \cpu_name
.long arm7tdmi_processor_functions
.long 0
.long 0
.long v4_cache_fns
- .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm7tdmi_proc_info arm7tdmi, 0x41007700, 0xfff8ff00, \
+ cpu_arm7tdmi_name
+ arm7tdmi_proc_info triscenda7, 0x0001d2ff, 0x0001ffff, \
+ cpu_triscenda7_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info at91, 0x14000040, 0xfff000e0, \
+ cpu_at91_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4510b, 0x36365000, 0xfffff000, \
+ cpu_s3c4510b_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4530, 0x4c000000, 0xfff000e0, \
+ cpu_s3c4530_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c3410, 0x34100000, 0xffff0000, \
+ cpu_s3c3410_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c44b0x, 0x44b00000, 0xffff0000, \
+ cpu_s3c44b0x_name, extra_hwcaps=HWCAP_THUMB
diff --git aosp-v3.0/arch/arm/mm/proc-arm920.S smdk4210/arch/arm/mm/proc-arm920.S
index bf8a1d1..0dea376 100644
--- aosp-v3.0/arch/arm/mm/proc-arm920.S
+++ smdk4210/arch/arm/mm/proc-arm920.S
@@ -315,18 +315,8 @@ ENTRY(arm920_dma_unmap_area)
mov pc, lr
ENDPROC(arm920_dma_unmap_area)
-ENTRY(arm920_cache_fns)
- .long arm920_flush_icache_all
- .long arm920_flush_kern_cache_all
- .long arm920_flush_user_cache_all
- .long arm920_flush_user_cache_range
- .long arm920_coherent_kern_range
- .long arm920_coherent_user_range
- .long arm920_flush_kern_dcache_area
- .long arm920_dma_map_area
- .long arm920_dma_unmap_area
- .long arm920_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm920
#endif
@@ -450,43 +440,14 @@ arm920_crval:
crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm920_processor_functions, #object
-arm920_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm920_proc_init
- .word cpu_arm920_proc_fin
- .word cpu_arm920_reset
- .word cpu_arm920_do_idle
- .word cpu_arm920_dcache_clean_area
- .word cpu_arm920_switch_mm
- .word cpu_arm920_set_pte_ext
- .word cpu_arm920_suspend_size
- .word cpu_arm920_do_suspend
- .word cpu_arm920_do_resume
- .size arm920_processor_functions, . - arm920_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm920, dabort=v4t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm920_name, #object
-cpu_arm920_name:
- .asciz "ARM920T"
- .size cpu_arm920_name, . - cpu_arm920_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm920_name, "ARM920T"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm922.S smdk4210/arch/arm/mm/proc-arm922.S
index 95ba1fc..490e188 100644
--- aosp-v3.0/arch/arm/mm/proc-arm922.S
+++ smdk4210/arch/arm/mm/proc-arm922.S
@@ -317,18 +317,8 @@ ENTRY(arm922_dma_unmap_area)
mov pc, lr
ENDPROC(arm922_dma_unmap_area)
-ENTRY(arm922_cache_fns)
- .long arm922_flush_icache_all
- .long arm922_flush_kern_cache_all
- .long arm922_flush_user_cache_all
- .long arm922_flush_user_cache_range
- .long arm922_coherent_kern_range
- .long arm922_coherent_user_range
- .long arm922_flush_kern_dcache_area
- .long arm922_dma_map_area
- .long arm922_dma_unmap_area
- .long arm922_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm922
#endif
@@ -420,43 +410,14 @@ arm922_crval:
crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm922_processor_functions, #object
-arm922_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm922_proc_init
- .word cpu_arm922_proc_fin
- .word cpu_arm922_reset
- .word cpu_arm922_do_idle
- .word cpu_arm922_dcache_clean_area
- .word cpu_arm922_switch_mm
- .word cpu_arm922_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm922_processor_functions, . - arm922_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm922, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm922_name, #object
-cpu_arm922_name:
- .asciz "ARM922T"
- .size cpu_arm922_name, . - cpu_arm922_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm922_name, "ARM922T"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm925.S smdk4210/arch/arm/mm/proc-arm925.S
index 541e477..51d494b 100644
--- aosp-v3.0/arch/arm/mm/proc-arm925.S
+++ smdk4210/arch/arm/mm/proc-arm925.S
@@ -372,17 +372,8 @@ ENTRY(arm925_dma_unmap_area)
mov pc, lr
ENDPROC(arm925_dma_unmap_area)
-ENTRY(arm925_cache_fns)
- .long arm925_flush_icache_all
- .long arm925_flush_kern_cache_all
- .long arm925_flush_user_cache_all
- .long arm925_flush_user_cache_range
- .long arm925_coherent_kern_range
- .long arm925_coherent_user_range
- .long arm925_flush_kern_dcache_area
- .long arm925_dma_map_area
- .long arm925_dma_unmap_area
- .long arm925_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm925
ENTRY(cpu_arm925_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -487,52 +478,24 @@ arm925_crval:
crval clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm925_processor_functions, #object
-arm925_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm925_proc_init
- .word cpu_arm925_proc_fin
- .word cpu_arm925_reset
- .word cpu_arm925_do_idle
- .word cpu_arm925_dcache_clean_area
- .word cpu_arm925_switch_mm
- .word cpu_arm925_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm925_processor_functions, . - arm925_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm925, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm925_name, #object
-cpu_arm925_name:
- .asciz "ARM925T"
- .size cpu_arm925_name, . - cpu_arm925_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm925_name, "ARM925T"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm925_proc_info,#object
-__arm925_proc_info:
- .long 0x54029250
- .long 0xfffffff0
+.macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
@@ -550,27 +513,8 @@ __arm925_proc_info:
.long v4wbi_tlb_fns
.long v4wb_user_fns
.long arm925_cache_fns
- .size __arm925_proc_info, . - __arm925_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __arm915_proc_info,#object
-__arm915_proc_info:
- .long 0x54029150
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm925_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
- .long cpu_arm925_name
- .long arm925_processor_functions
- .long v4wbi_tlb_fns
- .long v4wb_user_fns
- .long arm925_cache_fns
- .size __arm925_proc_info, . - __arm925_proc_info
+ arm925_proc_info arm925, 0x54029250, 0xfffffff0, cpu_arm925_name
+ arm925_proc_info arm915, 0x54029150, 0xfffffff0, cpu_arm925_name
diff --git aosp-v3.0/arch/arm/mm/proc-arm926.S smdk4210/arch/arm/mm/proc-arm926.S
index 0ed85d9..b2f9bde 100644
--- aosp-v3.0/arch/arm/mm/proc-arm926.S
+++ smdk4210/arch/arm/mm/proc-arm926.S
@@ -335,17 +335,8 @@ ENTRY(arm926_dma_unmap_area)
mov pc, lr
ENDPROC(arm926_dma_unmap_area)
-ENTRY(arm926_cache_fns)
- .long arm926_flush_icache_all
- .long arm926_flush_kern_cache_all
- .long arm926_flush_user_cache_all
- .long arm926_flush_user_cache_range
- .long arm926_coherent_kern_range
- .long arm926_coherent_user_range
- .long arm926_flush_kern_dcache_area
- .long arm926_dma_map_area
- .long arm926_dma_unmap_area
- .long arm926_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm926
ENTRY(cpu_arm926_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -475,42 +466,14 @@ arm926_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm926_processor_functions, #object
-arm926_processor_functions:
- .word v5tj_early_abort
- .word legacy_pabort
- .word cpu_arm926_proc_init
- .word cpu_arm926_proc_fin
- .word cpu_arm926_reset
- .word cpu_arm926_do_idle
- .word cpu_arm926_dcache_clean_area
- .word cpu_arm926_switch_mm
- .word cpu_arm926_set_pte_ext
- .word cpu_arm926_suspend_size
- .word cpu_arm926_do_suspend
- .word cpu_arm926_do_resume
- .size arm926_processor_functions, . - arm926_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm926, dabort=v5tj_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5tej"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm926_name, #object
-cpu_arm926_name:
- .asciz "ARM926EJ-S"
- .size cpu_arm926_name, . - cpu_arm926_name
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
+ string cpu_arm926_name, "ARM926EJ-S"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm940.S smdk4210/arch/arm/mm/proc-arm940.S
index 26aea3f..ac750d5 100644
--- aosp-v3.0/arch/arm/mm/proc-arm940.S
+++ smdk4210/arch/arm/mm/proc-arm940.S
@@ -264,17 +264,8 @@ ENTRY(arm940_dma_unmap_area)
mov pc, lr
ENDPROC(arm940_dma_unmap_area)
-ENTRY(arm940_cache_fns)
- .long arm940_flush_icache_all
- .long arm940_flush_kern_cache_all
- .long arm940_flush_user_cache_all
- .long arm940_flush_user_cache_range
- .long arm940_coherent_kern_range
- .long arm940_coherent_user_range
- .long arm940_flush_kern_dcache_area
- .long arm940_dma_map_area
- .long arm940_dma_unmap_area
- .long arm940_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm940
__CPUINIT
@@ -348,42 +339,14 @@ __arm940_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm940_processor_functions, #object
-ENTRY(arm940_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm940_proc_init
- .word cpu_arm940_proc_fin
- .word cpu_arm940_reset
- .word cpu_arm940_do_idle
- .word cpu_arm940_dcache_clean_area
- .word cpu_arm940_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm940_processor_functions, . - arm940_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm940, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
-.type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm940_name, #object
-cpu_arm940_name:
- .ascii "ARM940T"
- .size cpu_arm940_name, . - cpu_arm940_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm940_name, "ARM940T"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm946.S smdk4210/arch/arm/mm/proc-arm946.S
index 8063345..f8f7ea3 100644
--- aosp-v3.0/arch/arm/mm/proc-arm946.S
+++ smdk4210/arch/arm/mm/proc-arm946.S
@@ -306,18 +306,8 @@ ENTRY(arm946_dma_unmap_area)
mov pc, lr
ENDPROC(arm946_dma_unmap_area)
-ENTRY(arm946_cache_fns)
- .long arm946_flush_icache_all
- .long arm946_flush_kern_cache_all
- .long arm946_flush_user_cache_all
- .long arm946_flush_user_cache_range
- .long arm946_coherent_kern_range
- .long arm946_coherent_user_range
- .long arm946_flush_kern_dcache_area
- .long arm946_dma_map_area
- .long arm946_dma_unmap_area
- .long arm946_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm946
ENTRY(cpu_arm946_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -403,43 +393,14 @@ __arm946_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm946_processor_functions, #object
-ENTRY(arm946_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm946_proc_init
- .word cpu_arm946_proc_fin
- .word cpu_arm946_reset
- .word cpu_arm946_do_idle
-
- .word cpu_arm946_dcache_clean_area
- .word cpu_arm946_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm946_processor_functions, . - arm946_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm946, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5t"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm946_name, #object
-cpu_arm946_name:
- .ascii "ARM946E-S"
- .size cpu_arm946_name, . - cpu_arm946_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5t"
+ string cpu_arm946_name, "ARM946E-S"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-arm9tdmi.S smdk4210/arch/arm/mm/proc-arm9tdmi.S
index 546b54d..2120f9e 100644
--- aosp-v3.0/arch/arm/mm/proc-arm9tdmi.S
+++ smdk4210/arch/arm/mm/proc-arm9tdmi.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm9tdmi_proc_init()
@@ -55,82 +57,38 @@ __arm9tdmi_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm9tdmi_processor_functions, #object
-ENTRY(arm9tdmi_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm9tdmi_proc_init
- .word cpu_arm9tdmi_proc_fin
- .word cpu_arm9tdmi_reset
- .word cpu_arm9tdmi_do_idle
- .word cpu_arm9tdmi_dcache_clean_area
- .word cpu_arm9tdmi_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm9tdmi, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm9tdmi_name, #object
-cpu_arm9tdmi_name:
- .asciz "ARM9TDMI"
- .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name
-
- .type cpu_p2001_name, #object
-cpu_p2001_name:
- .asciz "P2001"
- .size cpu_p2001_name, . - cpu_p2001_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm9tdmi_name, "ARM9TDMI"
+ string cpu_p2001_name, "P2001"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm9tdmi_proc_info, #object
-__arm9tdmi_proc_info:
- .long 0x41009900
- .long 0xfff8ff00
+.macro arm9tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long 0
.long 0
b __arm9tdmi_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_arm9tdmi_name
+ .long \cpu_name
.long arm9tdmi_processor_functions
.long 0
.long 0
.long v4_cache_fns
- .size __arm9tdmi_proc_info, . - __arm9tdmi_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __p2001_proc_info, #object
-__p2001_proc_info:
- .long 0x41029000
- .long 0xffffffff
- .long 0
- .long 0
- b __arm9tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_p2001_name
- .long arm9tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __p2001_proc_info, . - __p2001_proc_info
+ arm9tdmi_proc_info arm9tdmi, 0x41009900, 0xfff8ff00, cpu_arm9tdmi_name
+ arm9tdmi_proc_info p2001, 0x41029000, 0xffffffff, cpu_p2001_name
diff --git aosp-v3.0/arch/arm/mm/proc-fa526.S smdk4210/arch/arm/mm/proc-fa526.S
index fc2a4ae..4c7a571 100644
--- aosp-v3.0/arch/arm/mm/proc-fa526.S
+++ smdk4210/arch/arm/mm/proc-fa526.S
@@ -180,42 +180,14 @@ fa526_cr1_set:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type fa526_processor_functions, #object
-fa526_processor_functions:
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_fa526_proc_init
- .word cpu_fa526_proc_fin
- .word cpu_fa526_reset
- .word cpu_fa526_do_idle
- .word cpu_fa526_dcache_clean_area
- .word cpu_fa526_switch_mm
- .word cpu_fa526_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size fa526_processor_functions, . - fa526_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions fa526, dabort=v4_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_fa526_name, #object
-cpu_fa526_name:
- .asciz "FA526"
- .size cpu_fa526_name, . - cpu_fa526_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_fa526_name, "FA526"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-feroceon.S smdk4210/arch/arm/mm/proc-feroceon.S
index d3883ee..8a6c2f7 100644
--- aosp-v3.0/arch/arm/mm/proc-feroceon.S
+++ smdk4210/arch/arm/mm/proc-feroceon.S
@@ -411,29 +411,28 @@ ENTRY(feroceon_dma_unmap_area)
mov pc, lr
ENDPROC(feroceon_dma_unmap_area)
-ENTRY(feroceon_cache_fns)
- .long feroceon_flush_icache_all
- .long feroceon_flush_kern_cache_all
- .long feroceon_flush_user_cache_all
- .long feroceon_flush_user_cache_range
- .long feroceon_coherent_kern_range
- .long feroceon_coherent_user_range
- .long feroceon_flush_kern_dcache_area
- .long feroceon_dma_map_area
- .long feroceon_dma_unmap_area
- .long feroceon_dma_flush_range
-
-ENTRY(feroceon_range_cache_fns)
- .long feroceon_flush_icache_all
- .long feroceon_flush_kern_cache_all
- .long feroceon_flush_user_cache_all
- .long feroceon_flush_user_cache_range
- .long feroceon_coherent_kern_range
- .long feroceon_coherent_user_range
- .long feroceon_range_flush_kern_dcache_area
- .long feroceon_range_dma_map_area
- .long feroceon_dma_unmap_area
- .long feroceon_range_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions feroceon
+
+.macro range_alias basename
+ .globl feroceon_range_\basename
+ .type feroceon_range_\basename , %function
+ .equ feroceon_range_\basename , feroceon_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for this case.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ range_alias flush_icache_all
+ range_alias flush_user_cache_all
+ range_alias flush_kern_cache_all
+ range_alias flush_user_cache_range
+ range_alias coherent_kern_range
+ range_alias coherent_user_range
+ range_alias dma_unmap_area
+
+ define_cache_functions feroceon_range
.align 5
ENTRY(cpu_feroceon_dcache_clean_area)
@@ -539,93 +538,27 @@ feroceon_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type feroceon_processor_functions, #object
-feroceon_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_feroceon_proc_init
- .word cpu_feroceon_proc_fin
- .word cpu_feroceon_reset
- .word cpu_feroceon_do_idle
- .word cpu_feroceon_dcache_clean_area
- .word cpu_feroceon_switch_mm
- .word cpu_feroceon_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size feroceon_processor_functions, . - feroceon_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions feroceon, dabort=v5t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_feroceon_name, #object
-cpu_feroceon_name:
- .asciz "Feroceon"
- .size cpu_feroceon_name, . - cpu_feroceon_name
-
- .type cpu_88fr531_name, #object
-cpu_88fr531_name:
- .asciz "Feroceon 88FR531-vd"
- .size cpu_88fr531_name, . - cpu_88fr531_name
-
- .type cpu_88fr571_name, #object
-cpu_88fr571_name:
- .asciz "Feroceon 88FR571-vd"
- .size cpu_88fr571_name, . - cpu_88fr571_name
-
- .type cpu_88fr131_name, #object
-cpu_88fr131_name:
- .asciz "Feroceon 88FR131"
- .size cpu_88fr131_name, . - cpu_88fr131_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_feroceon_name, "Feroceon"
+ string cpu_88fr531_name, "Feroceon 88FR531-vd"
+ string cpu_88fr571_name, "Feroceon 88FR571-vd"
+ string cpu_88fr131_name, "Feroceon 88FR131"
.align
.section ".proc.info.init", #alloc, #execinstr
-#ifdef CONFIG_CPU_FEROCEON_OLD_ID
- .type __feroceon_old_id_proc_info,#object
-__feroceon_old_id_proc_info:
- .long 0x41009260
- .long 0xff00fff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_feroceon_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_cache_fns
- .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
-#endif
-
- .type __88fr531_proc_info,#object
-__88fr531_proc_info:
- .long 0x56055310
- .long 0xfffffff0
+.macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -640,59 +573,22 @@ __88fr531_proc_info:
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr531_name
+ .long \cpu_name
.long feroceon_processor_functions
.long v4wbi_tlb_fns
.long feroceon_user_fns
- .long feroceon_cache_fns
- .size __88fr531_proc_info, . - __88fr531_proc_info
+ .long \cache
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __88fr571_proc_info,#object
-__88fr571_proc_info:
- .long 0x56155710
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr571_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_range_cache_fns
- .size __88fr571_proc_info, . - __88fr571_proc_info
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+ feroceon_proc_info feroceon_old_id, 0x41009260, 0xff00fff0, \
+ cpu_name=cpu_feroceon_name, cache=feroceon_cache_fns
+#endif
- .type __88fr131_proc_info,#object
-__88fr131_proc_info:
- .long 0x56251310
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr131_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_range_cache_fns
- .size __88fr131_proc_info, . - __88fr131_proc_info
+ feroceon_proc_info 88fr531, 0x56055310, 0xfffffff0, cpu_88fr531_name, \
+ cache=feroceon_cache_fns
+ feroceon_proc_info 88fr571, 0x56155710, 0xfffffff0, cpu_88fr571_name, \
+ cache=feroceon_range_cache_fns
+ feroceon_proc_info 88fr131, 0x56251310, 0xfffffff0, cpu_88fr131_name, \
+ cache=feroceon_range_cache_fns
diff --git aosp-v3.0/arch/arm/mm/proc-macros.S smdk4210/arch/arm/mm/proc-macros.S
index 34261f9..4ae9b44 100644
--- aosp-v3.0/arch/arm/mm/proc-macros.S
+++ smdk4210/arch/arm/mm/proc-macros.S
@@ -254,3 +254,66 @@
mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
mcr p15, 0, ip, c7, c10, 4 @ data write barrier
.endm
+
+.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0
+ .type \name\()_processor_functions, #object
+ .align 2
+ENTRY(\name\()_processor_functions)
+ .word \dabort
+ .word \pabort
+ .word cpu_\name\()_proc_init
+ .word cpu_\name\()_proc_fin
+ .word cpu_\name\()_reset
+ .word cpu_\name\()_do_idle
+ .word cpu_\name\()_dcache_clean_area
+ .word cpu_\name\()_switch_mm
+
+ .if \nommu
+ .word 0
+ .else
+ .word cpu_\name\()_set_pte_ext
+ .endif
+
+ .if \suspend
+ .word cpu_\name\()_suspend_size
+ .word cpu_\name\()_do_suspend
+ .word cpu_\name\()_do_resume
+ .else
+ .word 0
+ .word 0
+ .word 0
+ .endif
+
+ .size \name\()_processor_functions, . - \name\()_processor_functions
+.endm
+
+.macro define_cache_functions name:req
+ .align 2
+ .type \name\()_cache_fns, #object
+ENTRY(\name\()_cache_fns)
+ .long \name\()_flush_icache_all
+ .long \name\()_flush_kern_cache_all
+ .long \name\()_flush_user_cache_all
+ .long \name\()_flush_user_cache_range
+ .long \name\()_coherent_kern_range
+ .long \name\()_coherent_user_range
+ .long \name\()_flush_kern_dcache_area
+ .long \name\()_dma_map_area
+ .long \name\()_dma_unmap_area
+ .long \name\()_dma_flush_range
+ .size \name\()_cache_fns, . - \name\()_cache_fns
+.endm
+
+.macro define_tlb_functions name:req, flags_up:req, flags_smp
+ .type \name\()_tlb_fns, #object
+ENTRY(\name\()_tlb_fns)
+ .long \name\()_flush_user_tlb_range
+ .long \name\()_flush_kern_tlb_range
+ .ifnb \flags_smp
+ ALT_SMP(.long \flags_smp )
+ ALT_UP(.long \flags_up )
+ .else
+ .long \flags_up
+ .endif
+ .size \name\()_tlb_fns, . - \name\()_tlb_fns
+.endm
diff --git aosp-v3.0/arch/arm/mm/proc-mohawk.S smdk4210/arch/arm/mm/proc-mohawk.S
index 9d4f2ae..db52b0f 100644
--- aosp-v3.0/arch/arm/mm/proc-mohawk.S
+++ smdk4210/arch/arm/mm/proc-mohawk.S
@@ -93,6 +93,17 @@ ENTRY(cpu_mohawk_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(mohawk_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(mohawk_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -288,16 +299,8 @@ ENTRY(mohawk_dma_unmap_area)
mov pc, lr
ENDPROC(mohawk_dma_unmap_area)
-ENTRY(mohawk_cache_fns)
- .long mohawk_flush_kern_cache_all
- .long mohawk_flush_user_cache_all
- .long mohawk_flush_user_cache_range
- .long mohawk_coherent_kern_range
- .long mohawk_coherent_user_range
- .long mohawk_flush_kern_dcache_area
- .long mohawk_dma_map_area
- .long mohawk_dma_unmap_area
- .long mohawk_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions mohawk
ENTRY(cpu_mohawk_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -373,42 +376,14 @@ mohawk_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type mohawk_processor_functions, #object
-mohawk_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_mohawk_proc_init
- .word cpu_mohawk_proc_fin
- .word cpu_mohawk_reset
- .word cpu_mohawk_do_idle
- .word cpu_mohawk_dcache_clean_area
- .word cpu_mohawk_switch_mm
- .word cpu_mohawk_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size mohawk_processor_functions, . - mohawk_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions mohawk, dabort=v5t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_mohawk_name, #object
-cpu_mohawk_name:
- .asciz "Marvell 88SV331x"
- .size cpu_mohawk_name, . - cpu_mohawk_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_mohawk_name, "Marvell 88SV331x"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-sa110.S smdk4210/arch/arm/mm/proc-sa110.S
index 46f09ed..d50ada2 100644
--- aosp-v3.0/arch/arm/mm/proc-sa110.S
+++ smdk4210/arch/arm/mm/proc-sa110.S
@@ -187,43 +187,14 @@ sa110_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type sa110_processor_functions, #object
-ENTRY(sa110_processor_functions)
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_sa110_proc_init
- .word cpu_sa110_proc_fin
- .word cpu_sa110_reset
- .word cpu_sa110_do_idle
- .word cpu_sa110_dcache_clean_area
- .word cpu_sa110_switch_mm
- .word cpu_sa110_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size sa110_processor_functions, . - sa110_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa110, dabort=v4_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_sa110_name, #object
-cpu_sa110_name:
- .asciz "StrongARM-110"
- .size cpu_sa110_name, . - cpu_sa110_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa110_name, "StrongARM-110"
.align
diff --git aosp-v3.0/arch/arm/mm/proc-sa1100.S smdk4210/arch/arm/mm/proc-sa1100.S
index 184a9c9..c7e08ca 100644
--- aosp-v3.0/arch/arm/mm/proc-sa1100.S
+++ smdk4210/arch/arm/mm/proc-sa1100.S
@@ -236,59 +236,28 @@ sa1100_crval:
__INITDATA
/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
-/*
* SA1100 and SA1110 share the same function calls
*/
- .type sa1100_processor_functions, #object
-ENTRY(sa1100_processor_functions)
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_sa1100_proc_init
- .word cpu_sa1100_proc_fin
- .word cpu_sa1100_reset
- .word cpu_sa1100_do_idle
- .word cpu_sa1100_dcache_clean_area
- .word cpu_sa1100_switch_mm
- .word cpu_sa1100_set_pte_ext
- .word cpu_sa1100_suspend_size
- .word cpu_sa1100_do_suspend
- .word cpu_sa1100_do_resume
- .size sa1100_processor_functions, . - sa1100_processor_functions
-
- .section ".rodata"
-
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1
- .type cpu_sa1100_name, #object
-cpu_sa1100_name:
- .asciz "StrongARM-1100"
- .size cpu_sa1100_name, . - cpu_sa1100_name
+ .section ".rodata"
- .type cpu_sa1110_name, #object
-cpu_sa1110_name:
- .asciz "StrongARM-1110"
- .size cpu_sa1110_name, . - cpu_sa1110_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa1100_name, "StrongARM-1100"
+ string cpu_sa1110_name, "StrongARM-1110"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __sa1100_proc_info,#object
-__sa1100_proc_info:
- .long 0x4401a110
- .long 0xfffffff0
+.macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -301,32 +270,13 @@ __sa1100_proc_info:
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
- .long cpu_sa1100_name
+ .long \cpu_name
.long sa1100_processor_functions
.long v4wb_tlb_fns
.long v4_mc_user_fns
.long v4wb_cache_fns
- .size __sa1100_proc_info, . - __sa1100_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __sa1110_proc_info,#object
-__sa1110_proc_info:
- .long 0x6901b110
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __sa1100_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
- .long cpu_sa1110_name
- .long sa1100_processor_functions
- .long v4wb_tlb_fns
- .long v4_mc_user_fns
- .long v4wb_cache_fns
- .size __sa1110_proc_info, . - __sa1110_proc_info
+ sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name
+ sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name
diff --git aosp-v3.0/arch/arm/mm/proc-v6.S smdk4210/arch/arm/mm/proc-v6.S
index 1d2b845..aedf3c5 100644
--- aosp-v3.0/arch/arm/mm/proc-v6.S
+++ smdk4210/arch/arm/mm/proc-v6.S
@@ -56,6 +56,11 @@ ENTRY(cpu_v6_proc_fin)
*/
.align 5
ENTRY(cpu_v6_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 4 @ ISB
mov pc, r0
/*
@@ -169,11 +174,7 @@ cpu_resume_l1_flags:
#define cpu_v6_do_resume 0
#endif
-
- .type cpu_v6_name, #object
-cpu_v6_name:
- .asciz "ARMv6-compatible processor"
- .size cpu_v6_name, . - cpu_v6_name
+ string cpu_v6_name, "ARMv6-compatible processor"
.align
@@ -239,33 +240,13 @@ v6_crval:
__INITDATA
- .type v6_processor_functions, #object
-ENTRY(v6_processor_functions)
- .word v6_early_abort
- .word v6_pabort
- .word cpu_v6_proc_init
- .word cpu_v6_proc_fin
- .word cpu_v6_reset
- .word cpu_v6_do_idle
- .word cpu_v6_dcache_clean_area
- .word cpu_v6_switch_mm
- .word cpu_v6_set_pte_ext
- .word cpu_v6_suspend_size
- .word cpu_v6_do_suspend
- .word cpu_v6_do_resume
- .size v6_processor_functions, . - v6_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions v6, dabort=v6_early_abort, pabort=v6_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv6"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v6"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv6"
+ string cpu_elf_name, "v6"
.align
.section ".proc.info.init", #alloc, #execinstr
diff --git aosp-v3.0/arch/arm/mm/proc-v7.S smdk4210/arch/arm/mm/proc-v7.S
index 21cd298..e168799 100644
--- aosp-v3.0/arch/arm/mm/proc-v7.S
+++ smdk4210/arch/arm/mm/proc-v7.S
@@ -17,6 +17,8 @@
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
+#include <mach/smc.h>
+
#include "proc-macros.S"
#define TTB_S (1 << 1)
@@ -58,9 +60,16 @@ ENDPROC(cpu_v7_proc_fin)
* to what would be the reset vector.
*
* - loc - location to jump to for soft reset
+ *
+ * This code must be executed using a flat identity mapping with
+ * caches disabled.
*/
.align 5
ENTRY(cpu_v7_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ isb
mov pc, r0
ENDPROC(cpu_v7_reset)
@@ -173,8 +182,7 @@ ENTRY(cpu_v7_set_pte_ext)
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
-cpu_v7_name:
- .ascii "ARMv7 Processor"
+ string cpu_v7_name, "ARMv7 Processor"
.align
/*
@@ -275,13 +283,20 @@ cpu_resume_l1_flags:
* It is assumed that:
* - cache type register is implemented
*/
+__v7_ca5mp_setup:
__v7_ca9mp_setup:
+ mov r10, #(1 << 0) @ TLB ops broadcasting
+ b 1f
+__v7_ca15mp_setup:
+ mov r10, #0
+1:
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
- orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
- mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
+ orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode
+ orreq r0, r0, r10 @ Enable CPU-specific SMP bits
+ mcreq p15, 0, r0, c1, c0, 1
#endif
__v7_setup:
adr r12, __v7_setup_stack @ the local stack
@@ -322,12 +337,23 @@ __v7_setup:
orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit
mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register
#endif
- b 3f
+ b 4f
/* Cortex-A9 Errata */
2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
teq r0, r10
bne 3f
+#ifndef CONFIG_ARM_TRUSTZONE
+ cmp r6, #0x10 @ power ctrl reg added r1p0
+ mrcge p15, 0, r10, c15, c0, 0 @ read power control register
+ orrge r10, r10, #1 @ enable dynamic clock gating
+ mcrge p15, 0, r10, c15, c0, 0 @ write power control register
+#ifdef CONFIG_ARM_ERRATA_720791
+ teq r5, #0x00100000 @ only present in r1p*
+ mrceq p15, 0, r10, c15, c0, 2 @ read "chicken power ctrl" reg
+ orreq r10, r10, #0x30 @ disable core clk gate on
+ mcreq p15, 0, r10, c15, c0, 2 @ instr-side waits
+#endif
#ifdef CONFIG_ARM_ERRATA_742230
cmp r6, #0x22 @ only present up to r2p2
mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
@@ -343,6 +369,11 @@ __v7_setup:
orreq r10, r10, #1 << 22 @ set bit #22
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#ifdef CONFIG_ARM_ERRATA_761320
+ mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orr r10, r10, #1 << 21 @ set bit #21
+ mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
#ifdef CONFIG_ARM_ERRATA_743622
teq r5, #0x00200000 @ only present in r2p*
mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
@@ -355,8 +386,68 @@ __v7_setup:
orrlt r10, r10, #1 << 11 @ set bit #11
mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#endif
+ b 4f
+
+ /* Cortex-A15 Errata */
+3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
+ teq r0, r10
+ bne 4f
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ stmia r12, {r0-r3}
+ mov r3, #0
+#endif
+#ifdef CONFIG_ARM_ERRATA_761171
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #3 << 27 @ set [28:27] bit
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(1, 0, 0, 1)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#endif
+#ifdef CONFIG_ARM_ERRATA_762974
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ ldreq r10, =0x400 @ disable l2 prefetch function
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(15, 1, 0, 3)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 1, r10, c15, c0, 3 @ write l2 prefetch ctrl register
+#endif
+#endif
+#ifdef CONFIG_ARM_ERRATA_763722
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ teqne r6, #0x3 @ present in r0p3
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #15 << 25 @ set [28:25] bit
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(1, 0, 0, 1)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#endif
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldmia r12, {r0-r3}
+#endif
-3: mov r10, #0
+4: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
dsb
#ifdef CONFIG_MMU
@@ -415,94 +506,79 @@ __v7_setup_stack:
__INITDATA
- .type v7_processor_functions, #object
-ENTRY(v7_processor_functions)
- .word v7_early_abort
- .word v7_pabort
- .word cpu_v7_proc_init
- .word cpu_v7_proc_fin
- .word cpu_v7_reset
- .word cpu_v7_do_idle
- .word cpu_v7_dcache_clean_area
- .word cpu_v7_switch_mm
- .word cpu_v7_set_pte_ext
- .word cpu_v7_suspend_size
- .word cpu_v7_do_suspend
- .word cpu_v7_do_resume
- .size v7_processor_functions, . - v7_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+#ifdef CONFIG_PM_SLEEP
+ define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+#else
+ define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=0
+#endif
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv7"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v7"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv7"
+ string cpu_elf_name, "v7"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __v7_ca9mp_proc_info, #object
-__v7_ca9mp_proc_info:
- .long 0x410fc090 @ Required ID value
- .long 0xff0ffff0 @ Mask for ID
- ALT_SMP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_SMP)
- ALT_UP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_UP)
- .long PMD_TYPE_SECT | \
- PMD_SECT_XN | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- W(b) __v7_ca9mp_setup
+ /*
+ * Standard v7 proc info content
+ */
+.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_FLAGS_SMP | \mm_mmuflags)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_FLAGS_UP | \mm_mmuflags)
+ .long PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \io_mmuflags
+ W(b) \initfunc
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
+ HWCAP_EDSP | HWCAP_TLS | \hwcaps
.long cpu_v7_name
.long v7_processor_functions
.long v7wbi_tlb_fns
.long v6_user_fns
.long v7_cache_fns
+.endm
+
+ /*
+ * ARM Ltd. Cortex A5 processor.
+ */
+ .type __v7_ca5mp_proc_info, #object
+__v7_ca5mp_proc_info:
+ .long 0x410fc050
+ .long 0xff0ffff0
+ __v7_proc __v7_ca5mp_setup
+ .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A9 processor.
+ */
+ .type __v7_ca9mp_proc_info, #object
+__v7_ca9mp_proc_info:
+ .long 0x410fc090
+ .long 0xff0ffff0
+ __v7_proc __v7_ca9mp_setup
.size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
/*
+ * ARM Ltd. Cortex A15 processor.
+ */
+ .type __v7_ca15mp_proc_info, #object
+__v7_ca15mp_proc_info:
+ .long 0x410fc0f0
+ .long 0xff0ffff0
+ __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV
+ .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
+
+ /*
* Match any ARMv7 processor core.
*/
.type __v7_proc_info, #object
__v7_proc_info:
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
- ALT_SMP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_SMP)
- ALT_UP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_UP)
- .long PMD_TYPE_SECT | \
- PMD_SECT_XN | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- W(b) __v7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
- .long cpu_v7_name
- .long v7_processor_functions
- .long v7wbi_tlb_fns
- .long v6_user_fns
- .long v7_cache_fns
+ __v7_proc __v7_setup
.size __v7_proc_info, . - __v7_proc_info
diff --git aosp-v3.0/arch/arm/mm/proc-xsc3.S smdk4210/arch/arm/mm/proc-xsc3.S
index 5962136..1508f9b 100644
--- aosp-v3.0/arch/arm/mm/proc-xsc3.S
+++ smdk4210/arch/arm/mm/proc-xsc3.S
@@ -335,17 +335,8 @@ ENTRY(xsc3_dma_unmap_area)
mov pc, lr
ENDPROC(xsc3_dma_unmap_area)
-ENTRY(xsc3_cache_fns)
- .long xsc3_flush_icache_all
- .long xsc3_flush_kern_cache_all
- .long xsc3_flush_user_cache_all
- .long xsc3_flush_user_cache_range
- .long xsc3_coherent_kern_range
- .long xsc3_coherent_user_range
- .long xsc3_flush_kern_dcache_area
- .long xsc3_dma_map_area
- .long xsc3_dma_unmap_area
- .long xsc3_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xsc3
ENTRY(cpu_xsc3_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
@@ -503,52 +494,24 @@ xsc3_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type xsc3_processor_functions, #object
-ENTRY(xsc3_processor_functions)
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_xsc3_proc_init
- .word cpu_xsc3_proc_fin
- .word cpu_xsc3_reset
- .word cpu_xsc3_do_idle
- .word cpu_xsc3_dcache_clean_area
- .word cpu_xsc3_switch_mm
- .word cpu_xsc3_set_pte_ext
- .word cpu_xsc3_suspend_size
- .word cpu_xsc3_do_suspend
- .word cpu_xsc3_do_resume
- .size xsc3_processor_functions, . - xsc3_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xsc3, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_xsc3_name, #object
-cpu_xsc3_name:
- .asciz "XScale-V3 based processor"
- .size cpu_xsc3_name, . - cpu_xsc3_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_xsc3_name, "XScale-V3 based processor"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __xsc3_proc_info,#object
-__xsc3_proc_info:
- .long 0x69056000
- .long 0xffffe000
+.macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -566,29 +529,10 @@ __xsc3_proc_info:
.long v4wbi_tlb_fns
.long xsc3_mc_user_fns
.long xsc3_cache_fns
- .size __xsc3_proc_info, . - __xsc3_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
-/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+ xsc3_proc_info xsc3, 0x69056000, 0xffffe000
- .type __xsc3_pxa935_proc_info,#object
-__xsc3_pxa935_proc_info:
- .long 0x56056000
- .long 0xffffe000
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xsc3_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_xsc3_name
- .long xsc3_processor_functions
- .long v4wbi_tlb_fns
- .long xsc3_mc_user_fns
- .long xsc3_cache_fns
- .size __xsc3_pxa935_proc_info, . - __xsc3_pxa935_proc_info
+/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+ xsc3_proc_info xsc3_pxa935, 0x56056000, 0xffffe000
diff --git aosp-v3.0/arch/arm/mm/proc-xscale.S smdk4210/arch/arm/mm/proc-xscale.S
index 42af976..76a8046 100644
--- aosp-v3.0/arch/arm/mm/proc-xscale.S
+++ smdk4210/arch/arm/mm/proc-xscale.S
@@ -390,12 +390,12 @@ ENDPROC(xscale_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xscale_dma_a0_map_area)
+ENTRY(xscale_80200_A0_A1_dma_map_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
beq xscale_dma_clean_range
b xscale_dma_flush_range
-ENDPROC(xscale_dma_a0_map_area)
+ENDPROC(xscale_80200_A0_A1_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -407,17 +407,8 @@ ENTRY(xscale_dma_unmap_area)
mov pc, lr
ENDPROC(xscale_dma_unmap_area)
-ENTRY(xscale_cache_fns)
- .long xscale_flush_icache_all
- .long xscale_flush_kern_cache_all
- .long xscale_flush_user_cache_all
- .long xscale_flush_user_cache_range
- .long xscale_coherent_kern_range
- .long xscale_coherent_user_range
- .long xscale_flush_kern_dcache_area
- .long xscale_dma_map_area
- .long xscale_dma_unmap_area
- .long xscale_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale
/*
* On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
@@ -432,16 +423,28 @@ ENTRY(xscale_cache_fns)
* revision January 22, 2003, available at:
* http://www.intel.com/design/iio/specupdt/273415.htm
*/
-ENTRY(xscale_80200_A0_A1_cache_fns)
- .long xscale_flush_kern_cache_all
- .long xscale_flush_user_cache_all
- .long xscale_flush_user_cache_range
- .long xscale_coherent_kern_range
- .long xscale_coherent_user_range
- .long xscale_flush_kern_dcache_area
- .long xscale_dma_a0_map_area
- .long xscale_dma_unmap_area
- .long xscale_dma_flush_range
+.macro a0_alias basename
+ .globl xscale_80200_A0_A1_\basename
+ .type xscale_80200_A0_A1_\basename , %function
+ .equ xscale_80200_A0_A1_\basename , xscale_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for these processor revisions.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ a0_alias flush_icache_all
+ a0_alias flush_user_cache_all
+ a0_alias flush_kern_cache_all
+ a0_alias flush_user_cache_range
+ a0_alias coherent_kern_range
+ a0_alias coherent_user_range
+ a0_alias flush_kern_dcache_area
+ a0_alias dma_flush_range
+ a0_alias dma_unmap_area
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale_80200_A0_A1
ENTRY(cpu_xscale_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -587,432 +590,74 @@ xscale_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type xscale_processor_functions, #object
-ENTRY(xscale_processor_functions)
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_xscale_proc_init
- .word cpu_xscale_proc_fin
- .word cpu_xscale_reset
- .word cpu_xscale_do_idle
- .word cpu_xscale_dcache_clean_area
- .word cpu_xscale_switch_mm
- .word cpu_xscale_set_pte_ext
- .word cpu_xscale_suspend_size
- .word cpu_xscale_do_suspend
- .word cpu_xscale_do_resume
- .size xscale_processor_functions, . - xscale_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xscale, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_80200_A0_A1_name, #object
-cpu_80200_A0_A1_name:
- .asciz "XScale-80200 A0/A1"
- .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name
-
- .type cpu_80200_name, #object
-cpu_80200_name:
- .asciz "XScale-80200"
- .size cpu_80200_name, . - cpu_80200_name
-
- .type cpu_80219_name, #object
-cpu_80219_name:
- .asciz "XScale-80219"
- .size cpu_80219_name, . - cpu_80219_name
-
- .type cpu_8032x_name, #object
-cpu_8032x_name:
- .asciz "XScale-IOP8032x Family"
- .size cpu_8032x_name, . - cpu_8032x_name
-
- .type cpu_8033x_name, #object
-cpu_8033x_name:
- .asciz "XScale-IOP8033x Family"
- .size cpu_8033x_name, . - cpu_8033x_name
-
- .type cpu_pxa250_name, #object
-cpu_pxa250_name:
- .asciz "XScale-PXA250"
- .size cpu_pxa250_name, . - cpu_pxa250_name
-
- .type cpu_pxa210_name, #object
-cpu_pxa210_name:
- .asciz "XScale-PXA210"
- .size cpu_pxa210_name, . - cpu_pxa210_name
-
- .type cpu_ixp42x_name, #object
-cpu_ixp42x_name:
- .asciz "XScale-IXP42x Family"
- .size cpu_ixp42x_name, . - cpu_ixp42x_name
-
- .type cpu_ixp43x_name, #object
-cpu_ixp43x_name:
- .asciz "XScale-IXP43x Family"
- .size cpu_ixp43x_name, . - cpu_ixp43x_name
-
- .type cpu_ixp46x_name, #object
-cpu_ixp46x_name:
- .asciz "XScale-IXP46x Family"
- .size cpu_ixp46x_name, . - cpu_ixp46x_name
-
- .type cpu_ixp2400_name, #object
-cpu_ixp2400_name:
- .asciz "XScale-IXP2400"
- .size cpu_ixp2400_name, . - cpu_ixp2400_name
-
- .type cpu_ixp2800_name, #object
-cpu_ixp2800_name:
- .asciz "XScale-IXP2800"
- .size cpu_ixp2800_name, . - cpu_ixp2800_name
-
- .type cpu_pxa255_name, #object
-cpu_pxa255_name:
- .asciz "XScale-PXA255"
- .size cpu_pxa255_name, . - cpu_pxa255_name
-
- .type cpu_pxa270_name, #object
-cpu_pxa270_name:
- .asciz "XScale-PXA270"
- .size cpu_pxa270_name, . - cpu_pxa270_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+
+ string cpu_80200_A0_A1_name, "XScale-80200 A0/A1"
+ string cpu_80200_name, "XScale-80200"
+ string cpu_80219_name, "XScale-80219"
+ string cpu_8032x_name, "XScale-IOP8032x Family"
+ string cpu_8033x_name, "XScale-IOP8033x Family"
+ string cpu_pxa250_name, "XScale-PXA250"
+ string cpu_pxa210_name, "XScale-PXA210"
+ string cpu_ixp42x_name, "XScale-IXP42x Family"
+ string cpu_ixp43x_name, "XScale-IXP43x Family"
+ string cpu_ixp46x_name, "XScale-IXP46x Family"
+ string cpu_ixp2400_name, "XScale-IXP2400"
+ string cpu_ixp2800_name, "XScale-IXP2800"
+ string cpu_pxa255_name, "XScale-PXA255"
+ string cpu_pxa270_name, "XScale-PXA270"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __80200_A0_A1_proc_info,#object
-__80200_A0_A1_proc_info:
- .long 0x69052000
- .long 0xfffffffe
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80200_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_80200_A0_A1_cache_fns
- .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info
-
- .type __80200_proc_info,#object
-__80200_proc_info:
- .long 0x69052000
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
+.macro xscale_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
+ .long PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
b __xscale_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80200_name
+ .long \cpu_name
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __80200_proc_info, . - __80200_proc_info
-
- .type __80219_proc_info,#object
-__80219_proc_info:
- .long 0x69052e20
- .long 0xffffffe0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80219_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __80219_proc_info, . - __80219_proc_info
-
- .type __8032x_proc_info,#object
-__8032x_proc_info:
- .long 0x69052420
- .long 0xfffff7e0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_8032x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __8032x_proc_info, . - __8032x_proc_info
-
- .type __8033x_proc_info,#object
-__8033x_proc_info:
- .long 0x69054010
- .long 0xfffffd30
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_8033x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __8033x_proc_info, . - __8033x_proc_info
-
- .type __pxa250_proc_info,#object
-__pxa250_proc_info:
- .long 0x69052100
- .long 0xfffff7f0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa250_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa250_proc_info, . - __pxa250_proc_info
-
- .type __pxa210_proc_info,#object
-__pxa210_proc_info:
- .long 0x69052120
- .long 0xfffff3f0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa210_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa210_proc_info, . - __pxa210_proc_info
-
- .type __ixp2400_proc_info, #object
-__ixp2400_proc_info:
- .long 0x69054190
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp2400_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp2400_proc_info, . - __ixp2400_proc_info
-
- .type __ixp2800_proc_info, #object
-__ixp2800_proc_info:
- .long 0x690541a0
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp2800_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp2800_proc_info, . - __ixp2800_proc_info
-
- .type __ixp42x_proc_info, #object
-__ixp42x_proc_info:
- .long 0x690541c0
- .long 0xffffffc0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp42x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp42x_proc_info, . - __ixp42x_proc_info
-
- .type __ixp43x_proc_info, #object
-__ixp43x_proc_info:
- .long 0x69054040
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp43x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp43x_proc_info, . - __ixp43x_proc_info
-
- .type __ixp46x_proc_info, #object
-__ixp46x_proc_info:
- .long 0x69054200
- .long 0xffffff00
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp46x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp46x_proc_info, . - __ixp46x_proc_info
-
- .type __pxa255_proc_info,#object
-__pxa255_proc_info:
- .long 0x69052d00
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa255_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa255_proc_info, . - __pxa255_proc_info
-
- .type __pxa270_proc_info,#object
-__pxa270_proc_info:
- .long 0x69054110
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa270_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa270_proc_info, . - __pxa270_proc_info
-
+ .ifb \cache
+ .long xscale_cache_fns
+ .else
+ .long \cache
+ .endif
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ xscale_proc_info 80200_A0_A1, 0x69052000, 0xfffffffe, cpu_80200_name, \
+ cache=xscale_80200_A0_A1_cache_fns
+ xscale_proc_info 80200, 0x69052000, 0xfffffff0, cpu_80200_name
+ xscale_proc_info 80219, 0x69052e20, 0xffffffe0, cpu_80219_name
+ xscale_proc_info 8032x, 0x69052420, 0xfffff7e0, cpu_8032x_name
+ xscale_proc_info 8033x, 0x69054010, 0xfffffd30, cpu_8033x_name
+ xscale_proc_info pxa250, 0x69052100, 0xfffff7f0, cpu_pxa250_name
+ xscale_proc_info pxa210, 0x69052120, 0xfffff3f0, cpu_pxa210_name
+ xscale_proc_info ixp2400, 0x69054190, 0xfffffff0, cpu_ixp2400_name
+ xscale_proc_info ixp2800, 0x690541a0, 0xfffffff0, cpu_ixp2800_name
+ xscale_proc_info ixp42x, 0x690541c0, 0xffffffc0, cpu_ixp42x_name
+ xscale_proc_info ixp43x, 0x69054040, 0xfffffff0, cpu_ixp43x_name
+ xscale_proc_info ixp46x, 0x69054200, 0xffffff00, cpu_ixp46x_name
+ xscale_proc_info pxa255, 0x69052d00, 0xfffffff0, cpu_pxa255_name
+ xscale_proc_info pxa270, 0x69054110, 0xfffffff0, cpu_pxa270_name
diff --git aosp-v3.0/arch/arm/mm/tlb-fa.S smdk4210/arch/arm/mm/tlb-fa.S
index 9694f1f..7a2e56c 100644
--- aosp-v3.0/arch/arm/mm/tlb-fa.S
+++ smdk4210/arch/arm/mm/tlb-fa.S
@@ -67,9 +67,5 @@ ENTRY(fa_flush_kern_tlb_range)
__INITDATA
- .type fa_tlb_fns, #object
-ENTRY(fa_tlb_fns)
- .long fa_flush_user_tlb_range
- .long fa_flush_kern_tlb_range
- .long fa_tlb_flags
- .size fa_tlb_fns, . - fa_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions fa, fa_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v3.S smdk4210/arch/arm/mm/tlb-v3.S
index c10786e..d253995 100644
--- aosp-v3.0/arch/arm/mm/tlb-v3.S
+++ smdk4210/arch/arm/mm/tlb-v3.S
@@ -44,9 +44,5 @@ ENTRY(v3_flush_kern_tlb_range)
__INITDATA
- .type v3_tlb_fns, #object
-ENTRY(v3_tlb_fns)
- .long v3_flush_user_tlb_range
- .long v3_flush_kern_tlb_range
- .long v3_tlb_flags
- .size v3_tlb_fns, . - v3_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v3, v3_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v4.S smdk4210/arch/arm/mm/tlb-v4.S
index d6c9445..17a025a 100644
--- aosp-v3.0/arch/arm/mm/tlb-v4.S
+++ smdk4210/arch/arm/mm/tlb-v4.S
@@ -57,9 +57,5 @@ ENTRY(v4_flush_user_tlb_range)
__INITDATA
- .type v4_tlb_fns, #object
-ENTRY(v4_tlb_fns)
- .long v4_flush_user_tlb_range
- .long v4_flush_kern_tlb_range
- .long v4_tlb_flags
- .size v4_tlb_fns, . - v4_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4, v4_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v4wb.S smdk4210/arch/arm/mm/tlb-v4wb.S
index cb829ca..c04598f 100644
--- aosp-v3.0/arch/arm/mm/tlb-v4wb.S
+++ smdk4210/arch/arm/mm/tlb-v4wb.S
@@ -69,9 +69,5 @@ ENTRY(v4wb_flush_kern_tlb_range)
__INITDATA
- .type v4wb_tlb_fns, #object
-ENTRY(v4wb_tlb_fns)
- .long v4wb_flush_user_tlb_range
- .long v4wb_flush_kern_tlb_range
- .long v4wb_tlb_flags
- .size v4wb_tlb_fns, . - v4wb_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wb, v4wb_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v4wbi.S smdk4210/arch/arm/mm/tlb-v4wbi.S
index 60cfc4a..1f6062b 100644
--- aosp-v3.0/arch/arm/mm/tlb-v4wbi.S
+++ smdk4210/arch/arm/mm/tlb-v4wbi.S
@@ -60,9 +60,5 @@ ENTRY(v4wbi_flush_kern_tlb_range)
__INITDATA
- .type v4wbi_tlb_fns, #object
-ENTRY(v4wbi_tlb_fns)
- .long v4wbi_flush_user_tlb_range
- .long v4wbi_flush_kern_tlb_range
- .long v4wbi_tlb_flags
- .size v4wbi_tlb_fns, . - v4wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wbi, v4wbi_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v6.S smdk4210/arch/arm/mm/tlb-v6.S
index 73d7d89..a685944 100644
--- aosp-v3.0/arch/arm/mm/tlb-v6.S
+++ smdk4210/arch/arm/mm/tlb-v6.S
@@ -90,9 +90,5 @@ ENTRY(v6wbi_flush_kern_tlb_range)
__INIT
- .type v6wbi_tlb_fns, #object
-ENTRY(v6wbi_tlb_fns)
- .long v6wbi_flush_user_tlb_range
- .long v6wbi_flush_kern_tlb_range
- .long v6wbi_tlb_flags
- .size v6wbi_tlb_fns, . - v6wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v6wbi, v6wbi_tlb_flags
diff --git aosp-v3.0/arch/arm/mm/tlb-v7.S smdk4210/arch/arm/mm/tlb-v7.S
index 53cd5b4..ebd4290 100644
--- aosp-v3.0/arch/arm/mm/tlb-v7.S
+++ smdk4210/arch/arm/mm/tlb-v7.S
@@ -85,10 +85,5 @@ ENDPROC(v7wbi_flush_kern_tlb_range)
__INIT
- .type v7wbi_tlb_fns, #object
-ENTRY(v7wbi_tlb_fns)
- .long v7wbi_flush_user_tlb_range
- .long v7wbi_flush_kern_tlb_range
- ALT_SMP(.long v7wbi_tlb_flags_smp)
- ALT_UP(.long v7wbi_tlb_flags_up)
- .size v7wbi_tlb_fns, . - v7wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp
diff --git aosp-v3.0/arch/arm/plat-s3c24xx/cpu.c smdk4210/arch/arm/plat-s3c24xx/cpu.c
index 4a10c0f..3c46ff3 100644
--- aosp-v3.0/arch/arm/plat-s3c24xx/cpu.c
+++ smdk4210/arch/arm/plat-s3c24xx/cpu.c
@@ -230,19 +230,18 @@ static void s3c24xx_pm_restart(char mode, const char *cmd)
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
- unsigned long idcode = 0x0;
-
/* initialise the io descriptors we need for initialisation */
iotable_init(mach_desc, size);
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
if (cpu_architecture() >= CPU_ARCH_ARMv5) {
- idcode = s3c24xx_read_idcode_v5();
+ samsung_cpu_id = s3c24xx_read_idcode_v5();
} else {
- idcode = s3c24xx_read_idcode_v4();
+ samsung_cpu_id = s3c24xx_read_idcode_v4();
}
+ s3c24xx_init_cpu();
arm_pm_restart = s3c24xx_pm_restart;
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
diff --git aosp-v3.0/arch/arm/plat-s3c24xx/devs.c smdk4210/arch/arm/plat-s3c24xx/devs.c
index 7366799..a76bf2d 100644
--- aosp-v3.0/arch/arm/plat-s3c24xx/devs.c
+++ smdk4210/arch/arm/plat-s3c24xx/devs.c
@@ -150,9 +150,8 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
struct s3c2410fb_mach_info *npd;
- npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
+ npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
if (npd) {
- s3c_device_lcd.dev.platform_data = npd;
npd->displays = kmemdup(pd->displays,
sizeof(struct s3c2410fb_display) * npd->num_displays,
GFP_KERNEL);
@@ -188,12 +187,10 @@ struct platform_device s3c_device_ts = {
};
EXPORT_SYMBOL(s3c_device_ts);
-static struct s3c2410_ts_mach_info s3c2410ts_info;
-
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
{
- memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info));
- s3c_device_ts.dev.platform_data = &s3c2410ts_info;
+ s3c_set_platdata(hard_s3c2410ts_info,
+ sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
}
/* USB Device (Gadget)*/
@@ -223,15 +220,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
{
- struct s3c2410_udc_mach_info *npd;
-
- npd = kmalloc(sizeof(*npd), GFP_KERNEL);
- if (npd) {
- memcpy(npd, pd, sizeof(*npd));
- s3c_device_usbgadget.dev.platform_data = npd;
- } else {
- printk(KERN_ERR "no memory for udc platform data\n");
- }
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
}
/* USB High Speed 2.0 Device (Gadget) */
@@ -263,15 +252,7 @@ struct platform_device s3c_device_usb_hsudc = {
void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
{
- struct s3c24xx_hsudc_platdata *npd;
-
- npd = kmalloc(sizeof(*npd), GFP_KERNEL);
- if (npd) {
- memcpy(npd, pd, sizeof(*npd));
- s3c_device_usb_hsudc.dev.platform_data = npd;
- } else {
- printk(KERN_ERR "no memory for udc platform data\n");
- }
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
}
/* IIS */
@@ -383,13 +364,8 @@ EXPORT_SYMBOL(s3c_device_sdi);
void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
{
- struct s3c24xx_mci_pdata *npd;
-
- npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory to copy pdata", __func__);
-
- s3c_device_sdi.dev.platform_data = npd;
+ s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
+ &s3c_device_sdi);
}
diff --git aosp-v3.0/arch/arm/plat-s5p/Kconfig smdk4210/arch/arm/plat-s5p/Kconfig
index e98f5c5..f1eb177 100644
--- aosp-v3.0/arch/arm/plat-s5p/Kconfig
+++ smdk4210/arch/arm/plat-s5p/Kconfig
@@ -7,10 +7,10 @@
config PLAT_S5P
bool
- depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
default y
- select ARM_VIC if !ARCH_EXYNOS4
- select ARM_GIC if ARCH_EXYNOS4
+ select ARM_VIC if !ARCH_EXYNOS
+ select ARM_GIC if ARCH_EXYNOS
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select S3C_GPIO_TRACK
@@ -39,58 +39,239 @@ config S5P_GPIO_INT
config S5P_HRT
bool
+ select SAMSUNG_DEV_PWM
help
Use the High Resolution timer support
-comment "System MMU"
-
config S5P_SYSTEM_MMU
- bool "S5P SYSTEM MMU"
+ bool "System MMU for Exynos families"
depends on ARCH_EXYNOS4
+ select IOMMU_EXYNOS4_API
+ select IOVMM
help
Say Y here if you want to enable System MMU
+config S5P_SYSTEM_MMU_REFCOUNT
+ bool "Counting System MMU activations"
+ depends on S5P_SYSTEM_MMU
+ help
+ Say Y here if you want to enable counting System MMU enabling and
+ disabling.
+
+config S5P_SYSTEM_MMU_DEBUG
+ bool "Enables verbose debugging message about System MMU"
+ depends on S5P_SYSTEM_MMU
+ help
+ Say Y here if you need detailed message while System MMU driver works
+
+config S5P_SYSTEM_MMU_WA5250ERR
+ bool "Ensure 64KB-aligned mapping for DMA I/O buffers"
+ depends on S5P_SYSTEM_MMU && CPU_EXYNOS5250
+ default y
+ help
+ Select this to avoid unexpected fault occurred by System MMU v3.0.
+ This is just a makeshift option for those problems.
+
+ If unsure, n here.
+
+config IOVMM
+ bool
+ select GENERIC_ALLOCATOR
+
+config IOMMU_EXYNOS4_API
+ bool
+
+config S3C_DEV_FIMC
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Compile in platform device definitions for FIMC
+
config S5P_DEV_FIMC0
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 0
config S5P_DEV_FIMC1
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 1
config S5P_DEV_FIMC2
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 2
config S5P_DEV_FIMC3
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 3
+config S5P_DEV_I2C_HDMIPHY
+ bool
+ help
+ Compile in platform device definitions for I2C HDMIPHY controller
+
+config S5P_DEV_TV
+ bool
+ help
+ Compile in platform device definition for TV interface
+
+config S5P_DEV_MFC
+ bool
+ help
+ Compile in platform device definitions for MFC
+
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
+config S5P_DEV_FIMD1
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 1
+
+config S5P_DEV_DP
+ bool
+ help
+ Compile in platform device definitions for DP controller
+
+config S5P_DEV_TVOUT
+ bool "enable S5P_DEV_TVOUT"
+ depends on VIDEO_TVOUT
+ default y
+ help
+ Compile in platform device definitions for TVOUT
+
+config S5P_DEV_FIMG2D
+ bool
+ help
+ Compile in platform device definitions for FIMG2D controller
+
+config S5P_DEV_ROTATOR
+ bool
+ help
+ Compile in platform device definitions for ROTATOR
+
config S5P_DEV_ONENAND
bool
help
Compile in platform device definition for OneNAND controller
+config S5P_DEV_CSIS
+ bool
+ depends on VIDEO_FIMC_MIPI
+ default y
+ help
+ Compile in platform device definitions for MIPI-CSIS
+
config S5P_DEV_CSIS0
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in platform device definitions for MIPI-CSIS channel 0
config S5P_DEV_CSIS1
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in platform device definitions for MIPI-CSIS channel 1
+config S5P_DEV_JPEG
+ bool
+ depends on VIDEO_JPEG || VIDEO_JPEG_V2X
+ default y
+ help
+ Compile in platform device definitions for JPEG
+
config S5P_DEV_USB_EHCI
bool
help
Compile in platform device definition for USB EHCI
+config S5P_DEV_FIMD_S5P
+ bool
+ help
+ Compile in platform device definitions for FIMD controller
+
+config S5P_DEV_USBGADGET
+ bool
+ help
+ compile in platform device definitions for USB-GADGET
+
+config S5P_DEV_USB_SWITCH
+ bool
+ help
+ compile in platform device definitions for USB-SWITCH
+
config S5P_SETUP_MIPIPHY
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || S5P_MIPI_DSI2 || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
+config S5P_MEM_CMA
+ bool "Fixed memory through CMA"
+ select CMA
+ help
+ Use CMA(Contiguous memory allocator) to reserve machine specific memory.
+
+config S5P_DEV_THERMAL
+ bool
+ help
+ Compile in platform device definitions for THERMAL management unit.
+
+config S5P_DEV_ACE
+ bool
+ help
+ Compile in common setup code for Crypto Engine devices.
+
+config S5P_DEV_MIPI_DSI
+ bool
+ depends on FB_S5P_MIPI_DSIM
+ default y
+ help
+ Compile in platform device definitions for MIPI_DSI
+
+config S5P_DEV_DSIM02
+ bool
+ help
+ Compile in platform device definitions for MIPI-DSIM channel 0
+
+config S5P_DEV_DSIM12
+ bool
+ help
+ Compile in platform device definitions for MIPI-DSIM channel 1
+
+config S5P_BTS
+ bool "S5P BTS driver"
+ default n
+ help
+ Use Bus Traffic Shaper Driver
+
+config S5P_DEV_MIPI_DSIM
+ bool
+ depends on FB_MIPI_DSIM
+ default y
+ help
+ Compile in platform device definitions for MIPI_DSIM
+ to support mainlile style fimd
+
+config S3C_DEV_TSI
+ boolean "DEV TSI"
+ default n
+ ---help---
+ Compile in platform device definitions for S3C_DEV_TSI controller
diff --git aosp-v3.0/arch/arm/plat-s5p/Makefile smdk4210/arch/arm/plat-s5p/Makefile
index e234cc4..282efc6 100644
--- aosp-v3.0/arch/arm/plat-s5p/Makefile
+++ smdk4210/arch/arm/plat-s5p/Makefile
@@ -17,21 +17,51 @@ obj-y += dev-uart.o
obj-y += cpu.o
obj-y += clock.o
obj-y += irq.o
+obj-y += reset.o
+obj-y += reserve_mem.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
-obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
+obj-$(CONFIG_S5P_SYSTEM_MMU) += s5p-sysmmu.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
obj-$(CONFIG_S5P_HRT) += s5p-time.o
+obj-$(CONFIG_S5P_BTS) += bts.o
# devices
+obj-$(CONFIG_S3C_DEV_FIMC) += dev-fimc-s5p.o
obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
+obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
+obj-$(CONFIG_S5P_DEV_FIMD1) += dev-fimd1.o
+obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o
+obj-$(CONFIG_S5P_DEV_DP) += dev-dp.o
+obj-$(CONFIG_S5P_DEV_FIMD_S5P) += dev-fimd-s5p.o
+obj-$(CONFIG_S5P_DEV_TVOUT) += dev-tvout.o
+obj-$(CONFIG_S5P_DEV_TV) += dev-tv.o
+obj-$(CONFIG_S5P_DEV_FIMG2D) += dev-fimg2d.o
+obj-$(CONFIG_S5P_DEV_ROTATOR) += dev-rotator.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
+obj-$(CONFIG_S5P_DEV_CSIS) += dev-csis-s5p.o
+obj-$(CONFIG_S5P_DEV_JPEG) += dev-jpeg.o
obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
+obj-$(CONFIG_S5P_DEV_USB_SWITCH) += dev-usb-switch.o
+obj-$(CONFIG_S5P_DEV_USBGADGET) += dev-usbgadget.o
+obj-$(CONFIG_S5P_DEV_MIPI_DSI) += dev-dsim.o
+obj-$(CONFIG_S5P_DEV_DSIM02) += dev-dsim02.o
+obj-$(CONFIG_S5P_DEV_DSIM12) += dev-dsim12.o
+obj-$(CONFIG_S5P_DEV_MIPI_DSIM) += dev-mipidsim.o
obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+obj-$(CONFIG_EXYNOS4_SETUP_THERMAL) += dev-tmu.o
+obj-$(CONFIG_S5P_DEV_ACE) += dev-ace.o
+ifeq ($(CONFIG_ARCH_EXYNOS4), y)
+obj-$(CONFIG_IOMMU_EXYNOS4_API) += s5p_iommu.o
+obj-$(CONFIG_IOVMM) += s5p_iovmm.o
+endif
+obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o
+obj-$(CONFIG_S3C_DEV_TSI) += dev-tsi.o
diff --git aosp-v3.0/arch/arm/plat-s5p/clock.c smdk4210/arch/arm/plat-s5p/clock.c
index 8d081d9..7b4ec47 100644
--- aosp-v3.0/arch/arm/plat-s5p/clock.c
+++ smdk4210/arch/arm/plat-s5p/clock.c
@@ -40,6 +40,11 @@ struct clk clk_xusbxti = {
.id = -1,
};
+struct clk clk_xxti = {
+ .name = "xxti",
+ .id = -1,
+};
+
struct clk s5p_clk_27m = {
.name = "clk_27m",
.id = -1,
@@ -73,6 +78,7 @@ struct clk clk_fout_mpll = {
struct clk clk_fout_epll = {
.name = "fout_epll",
.id = -1,
+ .parent = &clk_ext_xtal_mux,
.ctrlbit = (1 << 31),
};
@@ -168,6 +174,41 @@ unsigned long s5p_epll_get_rate(struct clk *clk)
return clk->rate;
}
+int s5p_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+unsigned long s5p_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(pclk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+struct clk_ops s5p_sclk_spdif_ops = {
+ .set_rate = s5p_spdif_set_rate,
+ .get_rate = s5p_spdif_get_rate,
+};
+
static struct clk *s5p_clks[] __initdata = {
&clk_ext_xtal_mux,
&clk_48m,
@@ -179,6 +220,7 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_vpll,
&clk_vpll,
&clk_xusbxti,
+ &clk_xxti,
};
void __init s5p_register_clocks(unsigned long xtal_freq)
diff --git aosp-v3.0/arch/arm/plat-s5p/cpu.c smdk4210/arch/arm/plat-s5p/cpu.c
index bbc2aa7..15c3a39 100644
--- aosp-v3.0/arch/arm/plat-s5p/cpu.c
+++ smdk4210/arch/arm/plat-s5p/cpu.c
@@ -25,6 +25,7 @@
#include <plat/s5pc100.h>
#include <plat/s5pv210.h>
#include <plat/exynos4.h>
+#include <plat/exynos5.h>
/* table of supported CPUs */
@@ -33,48 +34,85 @@ static const char name_s5p6450[] = "S5P6450";
static const char name_s5pc100[] = "S5PC100";
static const char name_s5pv210[] = "S5PV210/S5PC110";
static const char name_exynos4210[] = "EXYNOS4210";
+static const char name_exynos4212[] = "EXYNOS4212";
+static const char name_exynos4412[] = "EXYNOS4412";
+static const char name_exynos5210[] = "EXYNOS5210";
+static const char name_exynos5250[] = "EXYNOS5250";
static struct cpu_table cpu_ids[] __initdata = {
{
- .idcode = 0x56440100,
- .idmask = 0xfffff000,
+ .idcode = S5P6440_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
.map_io = s5p6440_map_io,
.init_clocks = s5p6440_init_clocks,
.init_uarts = s5p6440_init_uarts,
.init = s5p64x0_init,
.name = name_s5p6440,
}, {
- .idcode = 0x36450000,
- .idmask = 0xfffff000,
+ .idcode = S5P6450_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
.map_io = s5p6450_map_io,
.init_clocks = s5p6450_init_clocks,
.init_uarts = s5p6450_init_uarts,
.init = s5p64x0_init,
.name = name_s5p6450,
}, {
- .idcode = 0x43100000,
- .idmask = 0xfffff000,
+ .idcode = S5PC100_CPU_ID,
+ .idmask = S5PC100_CPU_MASK,
.map_io = s5pc100_map_io,
.init_clocks = s5pc100_init_clocks,
.init_uarts = s5pc100_init_uarts,
.init = s5pc100_init,
.name = name_s5pc100,
}, {
- .idcode = 0x43110000,
- .idmask = 0xfffff000,
+ .idcode = S5PV210_CPU_ID,
+ .idmask = S5PV210_CPU_MASK,
.map_io = s5pv210_map_io,
.init_clocks = s5pv210_init_clocks,
.init_uarts = s5pv210_init_uarts,
.init = s5pv210_init,
.name = name_s5pv210,
}, {
- .idcode = 0x43210000,
- .idmask = 0xfffe0000,
+ .idcode = EXYNOS4210_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
.init_uarts = exynos4_init_uarts,
.init = exynos4_init,
.name = name_exynos4210,
+ }, {
+ .idcode = EXYNOS4212_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos4_map_io,
+ .init_clocks = exynos4_init_clocks,
+ .init_uarts = exynos4_init_uarts,
+ .init = exynos4_init,
+ .name = name_exynos4212,
+ }, {
+ .idcode = EXYNOS4412_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos4_map_io,
+ .init_clocks = exynos4_init_clocks,
+ .init_uarts = exynos4_init_uarts,
+ .init = exynos4_init,
+ .name = name_exynos4412,
+
+ }, {
+ .idcode = EXYNOS5210_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos5_map_io,
+ .init_clocks = exynos5_init_clocks,
+ .init_uarts = exynos5_init_uarts,
+ .init = exynos5_init,
+ .name = name_exynos5210,
+ }, {
+ .idcode = EXYNOS5250_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos5_map_io,
+ .init_clocks = exynos5_init_clocks,
+ .init_uarts = exynos5_init_uarts,
+ .init = exynos5_init,
+ .name = name_exynos5250,
},
};
@@ -106,21 +144,27 @@ static struct map_desc s5p_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5P_PA_SROMC),
.length = SZ_4K,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_HSPHY,
+ .pfn = __phys_to_pfn(S5P_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
},
};
/* read cpu identification code */
+unsigned long cpu_idcode;
void __init s5p_init_io(struct map_desc *mach_desc,
int size, void __iomem *cpuid_addr)
{
- unsigned long idcode;
-
/* initialize the io descriptors we need for initialization */
iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
if (mach_desc)
iotable_init(mach_desc, size);
- idcode = __raw_readl(cpuid_addr);
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ /* detect cpu id and rev. */
+ s5p_init_cpu(cpuid_addr);
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-csis0.c smdk4210/arch/arm/plat-s5p/dev-csis0.c
index e3aabef..69a7468 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-csis0.c
+++ smdk4210/arch/arm/plat-s5p/dev-csis0.c
@@ -12,16 +12,17 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <mach/map.h>
+#include <plat/mipi_csis.h>
static struct resource s5p_mipi_csis0_resource[] = {
[0] = {
.start = S5P_PA_MIPI_CSIS0,
- .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
+ .end = S5P_PA_MIPI_CSIS0 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_MIPI_CSIS0,
- .end = IRQ_MIPI_CSIS0,
+ .start = IRQ_MIPICSI0,
+ .end = IRQ_MIPICSI0,
.flags = IORESOURCE_IRQ,
}
};
@@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis0 = {
.num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
.resource = s5p_mipi_csis0_resource,
};
+
+struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data __initdata = {
+ .clk_rate = 166000000,
+ .lanes = 2,
+ .alignment = 32,
+ .hs_settle = 12,
+ .phy_enable = s5p_csis_phy_enable,
+};
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-csis1.c smdk4210/arch/arm/plat-s5p/dev-csis1.c
index 08b91b5..41a40c8 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-csis1.c
+++ smdk4210/arch/arm/plat-s5p/dev-csis1.c
@@ -12,16 +12,17 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <mach/map.h>
+#include <plat/mipi_csis.h>
static struct resource s5p_mipi_csis1_resource[] = {
[0] = {
.start = S5P_PA_MIPI_CSIS1,
- .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
+ .end = S5P_PA_MIPI_CSIS1 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_MIPI_CSIS1,
- .end = IRQ_MIPI_CSIS1,
+ .start = IRQ_MIPICSI1,
+ .end = IRQ_MIPICSI1,
.flags = IORESOURCE_IRQ,
},
};
@@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis1 = {
.num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
.resource = s5p_mipi_csis1_resource,
};
+
+struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data __initdata = {
+ .clk_rate = 166000000,
+ .lanes = 2,
+ .alignment = 32,
+ .hs_settle = 12,
+ .phy_enable = s5p_csis_phy_enable,
+};
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-ehci.c smdk4210/arch/arm/plat-s5p/dev-ehci.c
index 94080ff..5c5f5a5 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-ehci.c
+++ smdk4210/arch/arm/plat-s5p/dev-ehci.c
@@ -12,9 +12,13 @@
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
+#include <mach/gpio.h>
#include <plat/devs.h>
#include <plat/ehci.h>
#include <plat/usb-phy.h>
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+#include <mach/sec_modem.h>
+#endif
/* USB EHCI Host Controller registration */
static struct resource s5p_ehci_resource[] = {
@@ -54,4 +58,58 @@ void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
npd->phy_init = s5p_usb_phy_init;
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
+ if (!npd->phy_suspend)
+ npd->phy_suspend = s5p_usb_phy_suspend;
+ if (!npd->phy_resume)
+ npd->phy_resume = s5p_usb_phy_resume;
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ if (!npd->noti_host_states)
+ npd->noti_host_states = set_host_states;
+ if (!npd->get_cp_active_state)
+ npd->get_cp_active_state = get_cp_active_state;
+#endif
+}
+
+/* USB Host Controlle OHCI registrations */
+static struct resource s5p_ohci_resource[] = {
+ [0] = {
+ .start = S5P_PA_OHCI,
+ .end = S5P_PA_OHCI + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB_HOST,
+ .end = IRQ_USB_HOST,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s5p_device_ohci_dmamask = 0xffffffffUL;
+
+struct platform_device s5p_device_ohci = {
+ .name = "s5p-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_ohci_resource),
+ .resource = s5p_ohci_resource,
+ .dev = {
+ .dma_mask = &s5p_device_ohci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+void __init s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd)
+{
+ struct s5p_ohci_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_ohci_platdata),
+ &s5p_device_ohci);
+
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+ if (!npd->phy_suspend)
+ npd->phy_suspend = s5p_usb_phy_suspend;
+ if (!npd->phy_resume)
+ npd->phy_resume = s5p_usb_phy_resume;
}
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-fimc0.c smdk4210/arch/arm/plat-s5p/dev-fimc0.c
index 608770f..4045b9a 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-fimc0.c
+++ smdk4210/arch/arm/plat-s5p/dev-fimc0.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc0_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc0 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc0_default_data __initdata;
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-fimc1.c smdk4210/arch/arm/plat-s5p/dev-fimc1.c
index 76e3a97..c33fbce 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-fimc1.c
+++ smdk4210/arch/arm/plat-s5p/dev-fimc1.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc1_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc1 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc1_default_data __initdata;
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-fimc2.c smdk4210/arch/arm/plat-s5p/dev-fimc2.c
index 24d2981..ed98127 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-fimc2.c
+++ smdk4210/arch/arm/plat-s5p/dev-fimc2.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc2_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc2 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc2_default_data __initdata;
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-fimc3.c smdk4210/arch/arm/plat-s5p/dev-fimc3.c
index ef31bec..8fb3f01 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-fimc3.c
+++ smdk4210/arch/arm/plat-s5p/dev-fimc3.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc3_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc3 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc3_default_data __initdata;
diff --git aosp-v3.0/arch/arm/plat-s5p/dev-pmu.c smdk4210/arch/arm/plat-s5p/dev-pmu.c
index a08576d..2880f47 100644
--- aosp-v3.0/arch/arm/plat-s5p/dev-pmu.c
+++ smdk4210/arch/arm/plat-s5p/dev-pmu.c
@@ -15,22 +15,49 @@
#include <asm/pmu.h>
#include <mach/irqs.h>
-static struct resource s5p_pmu_resource = {
- .start = IRQ_PMU,
- .end = IRQ_PMU,
- .flags = IORESOURCE_IRQ,
+static struct resource s5p_pmu_resource[] = {
+ {
+ .start = IRQ_PMU,
+ .end = IRQ_PMU,
+ .flags = IORESOURCE_IRQ,
+ },
+#if CONFIG_NR_CPUS > 1
+ {
+ .start = IRQ_PMU_CPU1,
+ .end = IRQ_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+#if CONFIG_NR_CPUS > 2
+ {
+ .start = IRQ_PMU_CPU2,
+ .end = IRQ_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_PMU_CPU3,
+ .end = IRQ_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
};
struct platform_device s5p_device_pmu = {
.name = "arm-pmu",
.id = ARM_PMU_DEVICE_CPU,
- .num_resources = 1,
- .resource = &s5p_pmu_resource,
+ .num_resources = ARRAY_SIZE(s5p_pmu_resource),
+ .resource = s5p_pmu_resource,
};
static int __init s5p_pmu_init(void)
{
- platform_device_register(&s5p_device_pmu);
+ int ret;
+
+ ret = platform_device_register(&s5p_device_pmu);
+ if (ret) {
+ pr_warning("s5p_pmu_init: pmu device not registered.\n");
+ return ret;
+ }
+
return 0;
}
arch_initcall(s5p_pmu_init);
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/ehci.h smdk4210/arch/arm/plat-s5p/include/plat/ehci.h
index 6ae6810..0cdc0b5 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/ehci.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/ehci.h
@@ -14,8 +14,28 @@
struct s5p_ehci_platdata {
int (*phy_init)(struct platform_device *pdev, int type);
int (*phy_exit)(struct platform_device *pdev, int type);
+ int (*phy_suspend)(struct platform_device *pdev, int type);
+ int (*phy_resume)(struct platform_device *pdev, int type);
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+/* for SAMSUNG Modem*/
+ void (*noti_host_states)(struct platform_device *pdev, int type);
+ int (*get_cp_active_state)(void);
+#endif
+};
+
+struct s5p_ohci_platdata {
+ int (*phy_init)(struct platform_device *pdev, int type);
+ int (*phy_exit)(struct platform_device *pdev, int type);
+ int (*phy_suspend)(struct platform_device *pdev, int type);
+ int (*phy_resume)(struct platform_device *pdev, int type);
};
extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+extern void s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd);
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+int s5p_ehci_port_control(struct platform_device *pdev, int port, int enable);
+#endif
#endif /* __PLAT_S5P_EHCI_H */
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/exynos4.h smdk4210/arch/arm/plat-s5p/include/plat/exynos4.h
index 907caab..474a7c0 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/exynos4.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -12,11 +12,13 @@
/* Common init code for EXYNOS4 related SoCs */
-extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+struct s3c2410_uartcfg;
+
+extern void exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void exynos4_register_clocks(void);
extern void exynos4_setup_clocks(void);
-#ifdef CONFIG_CPU_EXYNOS4210
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_CPU_EXYNOS4212)
extern int exynos4_init(void);
extern void exynos4_init_irq(void);
@@ -24,7 +26,7 @@ extern void exynos4_map_io(void);
extern void exynos4_init_clocks(int xtal);
extern struct sys_timer exynos4_timer;
-#define exynos4_init_uarts exynos4_common_init_uarts
+#define exynos4_init_uarts exynos_common_init_uarts
#else
#define exynos4_init_clocks NULL
@@ -32,3 +34,15 @@ extern struct sys_timer exynos4_timer;
#define exynos4_map_io NULL
#define exynos4_init NULL
#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+extern void exynos4210_register_clocks(void);
+#else
+#define exynos4210_register_clocks() do { } while(0)
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4212)
+extern void exynos4212_register_clocks(void);
+#else
+#define exynos4212_register_clocks() do { } while(0)
+#endif
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/irqs.h smdk4210/arch/arm/plat-s5p/include/plat/irqs.h
index ba9121c..8f3f616 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/irqs.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/irqs.h
@@ -101,7 +101,11 @@
S5P_GPIOINT_GROUP_COUNT chips, each with total number of
S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
to any gpio chip with the s5p_register_gpio_interrupt() function */
+#ifdef CONFIG_MACH_MIDAS
+#define S5P_GPIOINT_GROUP_COUNT 5
+#else
#define S5P_GPIOINT_GROUP_COUNT 4
+#endif
#define S5P_GPIOINT_GROUP_SIZE 8
#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/map-s5p.h smdk4210/arch/arm/plat-s5p/include/plat/map-s5p.h
index d973d39..3e576956 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -20,8 +20,10 @@
#define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
+#define S5P_VA_GPIO4 S3C_ADDR(0x022C0000)
#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
+#define S5P_VA_SYSRAM_NS S3C_ADDR(0x02410000)
#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
@@ -35,12 +37,34 @@
#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
-#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
-#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
+
+#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000)
+#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000)
#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
+#define S5P_VA_AUDSS S3C_ADDR(0x02910000)
+
+#define S5P_VA_PPMU_DMC0 S3C_ADDR(0x02930000)
+#define S5P_VA_PPMU_DMC1 S3C_ADDR(0x02932000)
+#define S5P_VA_PPMU_CPU S3C_ADDR(0x02934000)
+
+#define S5P_VA_GDL S3C_ADDR(0x02940000)
+#define S5P_VA_GDR S3C_ADDR(0x02941000)
+
+#define S5P_VA_PPMU_DDR_C S3C_ADDR(0x02936000)
+#define S5P_VA_PPMU_DDR_R1 S3C_ADDR(0x02938000)
+#define S5P_VA_PPMU_DDR_L S3C_ADDR(0x0293a000)
+#define S5P_VA_PPMU_RIGHT0_BUS S3C_ADDR(0x0293c000)
+
+#define S5P_VA_SS_PHY S3C_ADDR(0x02A00000)
+#define S5P_VA_FIMCLITE0 S3C_ADDR(0x02A10000)
+#define S5P_VA_FIMCLITE1 S3C_ADDR(0x02A20000)
+#define S5P_VA_MIPICSI0 S3C_ADDR(0x02A30000)
+#define S5P_VA_MIPICSI1 S3C_ADDR(0x02A40000)
+#define S5P_VA_FIMCLITE2 S3C_ADDR(0x02A90000)
+
#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0 VA_VIC(0)
#define VA_VIC1 VA_VIC(1)
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/mipi_csis.h smdk4210/arch/arm/plat-s5p/include/plat/mipi_csis.h
index 9bd254c..561a8c6 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/mipi_csis.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/mipi_csis.h
@@ -39,5 +39,7 @@ struct s5p_platform_mipi_csis {
* false to disable D-PHY
*/
int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
+extern struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data;
+extern struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data;
#endif /* PLAT_S5P_MIPI_CSIS_H_ */
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/pll.h smdk4210/arch/arm/plat-s5p/include/plat/pll.h
index bf28fad..4b50b32 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/pll.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/pll.h
@@ -12,6 +12,59 @@
* published by the Free Software Foundation.
*/
+#define PLL35XX_MDIV_MASK (0x3FF)
+#define PLL35XX_PDIV_MASK (0x3F)
+#define PLL35XX_SDIV_MASK (0x7)
+#define PLL35XX_MDIV_SHIFT (16)
+#define PLL35XX_PDIV_SHIFT (8)
+#define PLL35XX_SDIV_SHIFT (0)
+
+#include <asm/div64.h>
+
+static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+#define PLL36XX_KDIV_MASK (0xFFFF)
+#define PLL36XX_MDIV_MASK (0x1FF)
+#define PLL36XX_PDIV_MASK (0x3F)
+#define PLL36XX_SDIV_MASK (0x7)
+#define PLL36XX_MDIV_SHIFT (16)
+#define PLL36XX_PDIV_SHIFT (8)
+#define PLL36XX_SDIV_SHIFT (0)
+
+static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
+ u32 pll_con0, u32 pll_con1)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+ kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+ tmp = baseclk;
+
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
+
#define PLL45XX_MDIV_MASK (0x3FF)
#define PLL45XX_PDIV_MASK (0x3F)
#define PLL45XX_SDIV_MASK (0x7)
@@ -19,8 +72,6 @@
#define PLL45XX_PDIV_SHIFT (8)
#define PLL45XX_SDIV_SHIFT (0)
-#include <asm/div64.h>
-
enum pll45xx_type_t {
pll_4500,
pll_4502,
@@ -72,7 +123,6 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
- kdiv = pll_con1 & PLL46XX_KDIV_MASK;
if (pll_type == pll_4650c)
kdiv = pll_con1 & PLL4650C_KDIV_MASK;
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/s5p-clock.h smdk4210/arch/arm/plat-s5p/include/plat/s5p-clock.h
index 2b6dcff..551ee10 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -18,6 +18,9 @@
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_bpll clk_ext_xtal_mux
+#define clk_fin_gpll clk_ext_xtal_mux
+#define clk_fin_cpll clk_ext_xtal_mux
#define clk_fin_mpll clk_ext_xtal_mux
#define clk_fin_epll clk_ext_xtal_mux
#define clk_fin_dpll clk_ext_xtal_mux
@@ -47,4 +50,9 @@ extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
extern int s5p_epll_enable(struct clk *clk, int enable);
extern unsigned long s5p_epll_get_rate(struct clk *clk);
+/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */
+extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long s5p_spdif_get_rate(struct clk *clk);
+
+extern struct clk_ops s5p_sclk_spdif_ops;
#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git aosp-v3.0/arch/arm/plat-s5p/include/plat/system-reset.h smdk4210/arch/arm/plat-s5p/include/plat/system-reset.h
index f307f34..9e0a095 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/system-reset.h
+++ smdk4210/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 aosp-v3.0/arch/arm/plat-s5p/include/plat/usb-phy.h smdk4210/arch/arm/plat-s5p/include/plat/usb-phy.h
index 6dd6bcf..9cd61e6 100644
--- aosp-v3.0/arch/arm/plat-s5p/include/plat/usb-phy.h
+++ smdk4210/arch/arm/plat-s5p/include/plat/usb-phy.h
@@ -14,9 +14,22 @@
enum s5p_usb_phy_type {
S5P_USB_PHY_DEVICE,
S5P_USB_PHY_HOST,
+ S5P_USB_PHY_DRD,
+ S5P_USB_PHY_OTGHOST,
};
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) || \
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+enum s5p_host_state {
+ S5P_HOST_OFF,
+ S5P_HOST_ON,
+};
+#endif
+
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_suspend(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_resume(struct platform_device *pdev, int type);
+extern int exynos4_check_usb_op(void);
#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git aosp-v3.0/arch/arm/plat-s5p/irq-eint.c smdk4210/arch/arm/plat-s5p/irq-eint.c
index b5bb774..2f08070 100644
--- aosp-v3.0/arch/arm/plat-s5p/irq-eint.c
+++ smdk4210/arch/arm/plat-s5p/irq-eint.c
@@ -65,6 +65,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 +116,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;
}
@@ -123,6 +129,7 @@ static struct irq_chip s5p_irq_eint = {
.irq_mask = s5p_irq_eint_mask,
.irq_unmask = s5p_irq_eint_unmask,
.irq_mask_ack = s5p_irq_eint_maskack,
+ .irq_disable = s5p_irq_eint_maskack,
.irq_ack = s5p_irq_eint_ack,
.irq_set_type = s5p_irq_eint_set_type,
#ifdef CONFIG_PM
@@ -138,11 +145,12 @@ static struct irq_chip s5p_irq_eint = {
*
* Each EINT pend/mask registers handle eight of them.
*/
-static inline void s5p_irq_demux_eint(unsigned int start)
+static inline u32 s5p_irq_demux_eint(unsigned int start)
{
u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
unsigned int irq;
+ u32 action = 0;
status &= ~mask;
status &= 0xff;
@@ -151,13 +159,21 @@ static inline void s5p_irq_demux_eint(unsigned int start)
irq = fls(status) - 1;
generic_handle_irq(irq + start);
status &= ~(1 << irq);
+ ++action;
}
+
+ return action;
}
static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
- s5p_irq_demux_eint(IRQ_EINT(16));
- s5p_irq_demux_eint(IRQ_EINT(24));
+ u32 a16_23, a24_31;
+
+ a16_23 = s5p_irq_demux_eint(IRQ_EINT(16));
+ a24_31 = s5p_irq_demux_eint(IRQ_EINT(24));
+
+ if (!a16_23 && !a24_31)
+ do_bad_IRQ(irq, desc);
}
static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
diff --git aosp-v3.0/arch/arm/plat-s5p/irq-gpioint.c smdk4210/arch/arm/plat-s5p/irq-gpioint.c
index 327ab9f..06c6bfb 100644
--- aosp-v3.0/arch/arm/plat-s5p/irq-gpioint.c
+++ smdk4210/arch/arm/plat-s5p/irq-gpioint.c
@@ -22,6 +22,10 @@
#include <mach/map.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+#include <asm/mach/irq.h>
+#include <mach/regs-gpio.h>
#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
@@ -46,22 +50,25 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = gc->chip_types;
unsigned int shift = (d->irq - gc->irq_base) << 2;
+ struct irq_desc *desc = irq_to_desc(d->irq);
+ unsigned int type_s5p = 0;
+ struct s3c_gpio_chip *chip = gc->private;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
- type = S5P_IRQ_TYPE_EDGE_RISING;
+ type_s5p = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
- type = S5P_IRQ_TYPE_EDGE_FALLING;
+ type_s5p = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
- type = S5P_IRQ_TYPE_EDGE_BOTH;
+ type_s5p = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_HIGH:
- type = S5P_IRQ_TYPE_LEVEL_HIGH;
+ type_s5p = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
case IRQ_TYPE_LEVEL_LOW:
- type = S5P_IRQ_TYPE_LEVEL_LOW;
+ type_s5p = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_NONE:
default:
@@ -70,29 +77,45 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
}
gc->type_cache &= ~(0x7 << shift);
- gc->type_cache |= type << shift;
+ gc->type_cache |= type_s5p << shift;
writel(gc->type_cache, gc->reg_base + ct->regs.type);
+
+ pr_info("%s irq:%d is at %s(%d)\n", __func__, d->irq, chip->chip.label,
+ (d->irq - chip->irq_base));
+
+ s3c_gpio_cfgpin(chip->chip.base + (d->irq - chip->irq_base), EINT_MODE);
+
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ desc->handle_irq = handle_edge_irq;
+ else
+ desc->handle_irq = handle_level_irq;
+
return 0;
}
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
- int group, pend_offset, mask_offset;
- unsigned int pend, mask;
+ int group, eint_offset;
+ unsigned int pend, mask, action = 0;
+
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
for (group = 0; group < bank->nr_groups; group++) {
struct s3c_gpio_chip *chip = bank->chips[group];
if (!chip)
continue;
-
- pend_offset = REG_OFFSET(group);
- pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
+ if (soc_is_exynos4210() || soc_is_exynos4212()
+ || soc_is_exynos4412()
+ || soc_is_exynos5250())
+ eint_offset = chip->eint_offset;
+ else
+ eint_offset = REG_OFFSET(group);
+ pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + eint_offset);
if (!pend)
continue;
-
- mask_offset = REG_OFFSET(group);
- mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + eint_offset);
pend &= ~mask;
while (pend) {
@@ -100,28 +123,38 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
int real_irq = chip->irq_base + offset;
generic_handle_irq(real_irq);
pend &= ~BIT(offset);
+ ++action;
}
}
+ chained_irq_exit(chip, desc);
+
+ if (!action)
+ do_bad_IRQ(irq, desc);
}
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
static int used_gpioint_groups = 0;
int group = chip->group;
- struct s5p_gpioint_bank *bank = NULL;
+ struct s5p_gpioint_bank *b, *bank = NULL;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
- if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+ if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) {
+ WARN(1, "used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT\n");
return -ENOMEM;
+ }
- list_for_each_entry(bank, &banks, list) {
- if (group >= bank->start &&
- group < bank->start + bank->nr_groups)
+ list_for_each_entry(b, &banks, list) {
+ if (group >= b->start && group < b->start + b->nr_groups) {
+ bank = b;
break;
+ }
}
- if (!bank)
+ if (!bank) {
+ WARN(1, "bank not found\n");
return -EINVAL;
+ }
if (!bank->handler) {
bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
@@ -149,16 +182,29 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
(void __iomem *)GPIO_BASE(chip),
handle_level_irq);
- if (!gc)
+ if (!gc) {
+ WARN(1, "irq_alloc_generic_chip failed\n");
return -ENOMEM;
+ }
+
+ gc->private = chip;
+
ct = gc->chip_types;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
- ct->chip.irq_set_type = s5p_gpioint_set_type,
- ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
- ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
- ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ ct->chip.irq_disable = irq_gc_mask_and_ack_set;
+ ct->chip.irq_set_type = s5p_gpioint_set_type;
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412()
+ || soc_is_exynos5250()) {
+ ct->regs.ack = PEND_OFFSET + chip->eint_offset;
+ ct->regs.mask = MASK_OFFSET + chip->eint_offset;
+ ct->regs.type = CON_OFFSET + chip->eint_offset;
+ } else {
+ ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ }
irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
@@ -189,6 +235,7 @@ int __init s5p_register_gpio_interrupt(int pin)
group);
return my_chip->irq_base + offset;
}
+
return ret;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/Kconfig smdk4210/arch/arm/plat-samsung/Kconfig
index 4d79519..74a4250 100644
--- aosp-v3.0/arch/arm/plat-samsung/Kconfig
+++ smdk4210/arch/arm/plat-samsung/Kconfig
@@ -15,6 +15,17 @@ config PLAT_SAMSUNG
if PLAT_SAMSUNG
+# vmalloc area and io map configurations
+
+comment "Base Address for SFR mapping"
+
+config S3C_ADDR_BASE
+ hex "S3C Base Address for SFR mapping"
+ default 0xF6000000
+ help
+ This value will be base address for S3C SFR mapping and
+ VMALLC_END should be less or euqal to this value.
+
# boot configurations
comment "Boot options"
@@ -149,6 +160,23 @@ config S3C_ADC
Core support for the ADC block found in the Samsung SoC systems
for drivers such as the touchscreen and hwmon to use to share
this resource.
+choice
+ prompt "Select ADC Number"
+ depends on S3C_ADC
+ default S3C_DEV_ADC
+
+config S3C_DEV_ADC
+ bool "ADC 0 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 0.
+
+config S3C_DEV_ADC1
+ bool "ADC 1 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 1.
+endchoice
# device definitions to compile in
@@ -172,6 +200,11 @@ config S3C_DEV_HSMMC3
help
Compile in platform device definitions for HSMMC channel 3
+config EXYNOS4_DEV_MSHC
+ bool
+ help
+ Compile in platform device definitions for MSHC
+
config S3C_DEV_HWMON
bool
help
@@ -212,6 +245,45 @@ config S3C_DEV_I2C7
help
Compile in platform device definition for I2C controller 7
+config S3C_DEV_I2C8_EMUL
+ depends on CPU_EXYNOS4210
+ bool "I2C8 Information GPIO bitbanging emulation"
+ help
+ Compile in platform device definitions for I2C channel 8
+
+config S3C_DEV_I2C9_EMUL
+ bool "I2C9 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 9
+
+config S3C_DEV_I2C11_EMUL
+ bool "I2C11 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 11
+
+config S3C_DEV_I2C14_EMUL
+ bool "I2C14 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 14
+
+config S3C_DEV_I2C16_EMUL
+ bool "I2C16 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 16
+
+config S3C_DEV_I2C17_EMUL
+ bool "I2C17 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 17.
+ This is used for usb hub 3803. Select this if USBHUB_USB3803
+ is selected.
+ If unsure, say N.
+
config S3C_DEV_FB
bool
help
@@ -227,6 +299,12 @@ config S3C_DEV_USB_HSOTG
help
Compile in platform device definition for USB high-speed OtG
+config EXYNOS_DEV_SS_UDC
+ bool
+ help
+ Compile in platform device definition for EXYNOS SuperSpeed USB 3.0
+ Device controller
+
config S3C_DEV_WDT
bool
default y if ARCH_S3C2410
@@ -260,6 +338,7 @@ config SAMSUNG_DEV_IDE
config S3C64XX_DEV_SPI
bool
+ default y if SPI_S3C64XX
help
Compile in platform device definitions for S3C64XX's type
SPI controllers.
@@ -267,7 +346,12 @@ config S3C64XX_DEV_SPI
config SAMSUNG_DEV_TS
bool
help
- Common in platform device definitions for touchscreen device
+ Common in platform device definitions for touchscreen device
+
+config SAMSUNG_DEV_TS1
+ bool
+ help
+ Common in platform device definitions for touchscreen-1 device
config SAMSUNG_DEV_KEYPAD
bool
@@ -280,6 +364,12 @@ config SAMSUNG_DEV_PWM
help
Compile in platform device definition for PWM Timer
+config SAMSUNG_DEV_BACKLIGHT
+ bool
+ depends on SAMSUNG_DEV_PWM
+ help
+ Compile in platform device definition LCD backlight with PWM Timer
+
config S3C24XX_PWM
bool "PWM device support"
select HAVE_PWM
@@ -300,6 +390,12 @@ config S3C_PL330_DMA
help
S3C DMA API Driver for PL330 DMAC.
+config DMA_M2M_TEST
+ tristate "S3C DMA API Test client"
+ help
+ Samsung DMA API test client. Say N unless you're debugging a
+ DMA Device driver.
+
comment "Power management"
config SAMSUNG_PM_DEBUG
diff --git aosp-v3.0/arch/arm/plat-samsung/Makefile smdk4210/arch/arm/plat-samsung/Makefile
index 53eb15b..ab0fa91 100644
--- aosp-v3.0/arch/arm/plat-samsung/Makefile
+++ smdk4210/arch/arm/plat-samsung/Makefile
@@ -11,7 +11,7 @@ obj- :=
# Objects we always build independent of SoC choice
-obj-y += init.o
+obj-y += init.o cpu.o
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
obj-y += clock.o
obj-y += pwm-clock.o
@@ -36,6 +36,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
+obj-$(CONFIG_EXYNOS4_DEV_MSHC) += dev-mshc.o
obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
@@ -50,6 +51,7 @@ obj-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.o
+obj-$(CONFIG_EXYNOS_DEV_SS_UDC) += dev-usb3-exynos-drd.o
obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
@@ -57,8 +59,10 @@ obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
+obj-$(CONFIG_SAMSUNG_DEV_TS1) += dev-ts1.o
obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o
-obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o
+obj-$(CONFIG_HAVE_PWM) += dev-pwm.o
+obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
# DMA support
@@ -66,6 +70,8 @@ obj-$(CONFIG_S3C_DMA) += dma.o
obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
+obj-$(CONFIG_DMA_M2M_TEST) += dma_m2m_test.o
+
# PM support
obj-$(CONFIG_PM) += pm.o
diff --git aosp-v3.0/arch/arm/plat-samsung/adc.c smdk4210/arch/arm/plat-samsung/adc.c
index e8f2be2..389e7e0 100644
--- aosp-v3.0/arch/arm/plat-samsung/adc.c
+++ smdk4210/arch/arm/plat-samsung/adc.c
@@ -39,24 +39,28 @@
*/
enum s3c_cpu_type {
- TYPE_S3C24XX,
- TYPE_S3C64XX
+ TYPE_ADCV1, /* S3C24XX */
+ TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */
+ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
+ TYPE_ADCV4, /* EXYNOS4412, EXYNOS5250 */
};
struct s3c_adc_client {
struct platform_device *pdev;
- struct list_head pend;
+ struct list_head pend;
wait_queue_head_t *wait;
- unsigned int nr_samples;
- int result;
- unsigned char is_ts;
- unsigned char channel;
+ unsigned int nr_samples;
+ int result;
+ unsigned char is_ts;
+ unsigned char channel;
void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
void (*convert_cb)(struct s3c_adc_client *c,
unsigned val1, unsigned val2,
unsigned *samples_left);
+ atomic_t running;
+ int error_count;
};
struct adc_device {
@@ -91,30 +95,37 @@ static inline void s3c_adc_select(struct adc_device *adc,
struct s3c_adc_client *client)
{
unsigned con = readl(adc->regs + S3C2410_ADCCON);
+ enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
client->select_cb(client, 1);
con &= ~S3C2410_ADCCON_MUXMASK;
con &= ~S3C2410_ADCCON_STDBM;
con &= ~S3C2410_ADCCON_STARTMASK;
-
- if (!client->is_ts)
- con |= S3C2410_ADCCON_SELMUX(client->channel);
+ con |= S3C2410_ADCCON_PRSCEN;
+
+ if (!client->is_ts) {
+ if (cpu >= TYPE_ADCV3)
+ writel(S5PV210_ADCCON_SELMUX(client->channel),
+ adc->regs + S5P_ADCMUX);
+ else
+ con |= S3C2410_ADCCON_SELMUX(client->channel);
+ }
writel(con, adc->regs + S3C2410_ADCCON);
}
static void s3c_adc_dbgshow(struct adc_device *adc)
{
- adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+ adc_dbg(adc, "CON=%08x, DLY=%08x\n",
readl(adc->regs + S3C2410_ADCCON),
- readl(adc->regs + S3C2410_ADCTSC),
readl(adc->regs + S3C2410_ADCDLY));
}
static void s3c_adc_try(struct adc_device *adc)
{
struct s3c_adc_client *next = adc->ts_pend;
+ unsigned int con = readl(adc->regs + S3C2410_ADCCON);
if (!next && !list_empty(&adc_pending)) {
next = list_first_entry(&adc_pending,
@@ -129,25 +140,43 @@ static void s3c_adc_try(struct adc_device *adc)
s3c_adc_select(adc, next);
s3c_adc_convert(adc);
s3c_adc_dbgshow(adc);
+ } else {
+ con &= ~S3C2410_ADCCON_PRSCEN;
+ con |= S3C2410_ADCCON_STDBM;
+ writel(con, adc->regs + S3C2410_ADCCON);
}
}
+static void s3c_convert_done(struct s3c_adc_client *client,
+ unsigned v, unsigned u, unsigned *left)
+{
+ client->result = v;
+ wake_up(client->wait);
+}
+
int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples)
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake)
{
struct adc_device *adc = adc_dev;
unsigned long flags;
- if (!adc) {
- printk(KERN_ERR "%s: failed to find adc\n", __func__);
- return -EINVAL;
- }
+ BUG_ON(!adc);
if (client->is_ts && adc->ts_pend)
return -EAGAIN;
+ if (atomic_xchg(&client->running, 1)) {
+ WARN(1, "%s: %p is already running\n", __func__, client);
+ return -EAGAIN;
+ }
+
spin_lock_irqsave(&adc->lock, flags);
+ client->convert_cb = s3c_convert_done;
+ client->wait = pwake;
+ client->result = -1;
+
client->channel = channel;
client->nr_samples = nr_samples;
@@ -165,30 +194,68 @@ int s3c_adc_start(struct s3c_adc_client *client,
}
EXPORT_SYMBOL_GPL(s3c_adc_start);
-static void s3c_convert_done(struct s3c_adc_client *client,
- unsigned v, unsigned u, unsigned *left)
+static void s3c_adc_stop(struct s3c_adc_client *client)
{
- client->result = v;
- wake_up(client->wait);
+ unsigned long flags;
+
+ spin_lock_irqsave(&adc_dev->lock, flags);
+
+ /* We should really check that nothing is in progress. */
+ if (adc_dev->cur == client)
+ adc_dev->cur = NULL;
+ if (adc_dev->ts_pend == client)
+ adc_dev->ts_pend = NULL;
+ else {
+ struct list_head *p, *n;
+ struct s3c_adc_client *tmp;
+
+ list_for_each_safe(p, n, &adc_pending) {
+ tmp = list_entry(p, struct s3c_adc_client, pend);
+ if (tmp == client)
+ list_del(&tmp->pend);
+ }
+ }
+
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__, client);
+
+ if (adc_dev->cur == NULL)
+ s3c_adc_try(adc_dev);
+
+ spin_unlock_irqrestore(&adc_dev->lock, flags);
}
int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+ struct adc_device *adc = adc_dev;
+ unsigned long flags;
int ret;
- client->convert_cb = s3c_convert_done;
- client->wait = &wake;
- client->result = -1;
-
- ret = s3c_adc_start(client, ch, 1);
+ ret = s3c_adc_start(client, ch, 1, &wake);
if (ret < 0)
goto err;
ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
if (client->result < 0) {
+ s3c_adc_stop(client);
+ dev_warn(&adc_dev->pdev->dev, "%s: %p is timed out\n",
+ __func__, client);
+ ++client->error_count;
+ BUG_ON(client->error_count > 10);
ret = -ETIMEDOUT;
goto err;
+ } else {
+ client->error_count = 0;
+
+ spin_lock_irqsave(&adc->lock, flags);
+ /* client->result >=0 means s3c_adc_irq ->
+ s3c_convert_done is running or finished. Make sure
+ it is *finished* (not running) by lock/unlocking
+ spin lock. Otherwise, after return of this
+ function, wake_up() on destroyed 'wake' may be
+ executed which will destroy stack */
+ spin_unlock_irqrestore(&adc->lock, flags);
}
client->convert_cb = NULL;
@@ -239,30 +306,7 @@ EXPORT_SYMBOL_GPL(s3c_adc_register);
void s3c_adc_release(struct s3c_adc_client *client)
{
- unsigned long flags;
-
- spin_lock_irqsave(&adc_dev->lock, flags);
-
- /* We should really check that nothing is in progress. */
- if (adc_dev->cur == client)
- adc_dev->cur = NULL;
- if (adc_dev->ts_pend == client)
- adc_dev->ts_pend = NULL;
- else {
- struct list_head *p, *n;
- struct s3c_adc_client *tmp;
-
- list_for_each_safe(p, n, &adc_pending) {
- tmp = list_entry(p, struct s3c_adc_client, pend);
- if (tmp == client)
- list_del(&tmp->pend);
- }
- }
-
- if (adc_dev->cur == NULL)
- s3c_adc_try(adc_dev);
-
- spin_unlock_irqrestore(&adc_dev->lock, flags);
+ s3c_adc_stop(client);
kfree(client);
}
EXPORT_SYMBOL_GPL(s3c_adc_release);
@@ -272,50 +316,60 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
struct adc_device *adc = pw;
struct s3c_adc_client *client = adc->cur;
enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
- unsigned data0, data1;
+ unsigned data0 = 0, data1 = 0;
- if (!client) {
+ spin_lock(&adc->lock);
+
+ if (!client || !client->nr_samples) {
dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
goto exit;
}
data0 = readl(adc->regs + S3C2410_ADCDAT0);
- data1 = readl(adc->regs + S3C2410_ADCDAT1);
+ if (cpu != TYPE_ADCV4)
+ data1 = readl(adc->regs + S3C2410_ADCDAT1);
+
adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
- client->nr_samples--;
+ if (client->nr_samples > 0)
+ client->nr_samples--;
- if (cpu == TYPE_S3C64XX) {
- /* S3C64XX ADC resolution is 12-bit */
- data0 &= 0xfff;
- data1 &= 0xfff;
- } else {
+ if (cpu == TYPE_ADCV1) {
data0 &= 0x3ff;
data1 &= 0x3ff;
+ } else {
+ /* S3C64XX/S5P ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
}
if (client->convert_cb)
(client->convert_cb)(client, data0, data1, &client->nr_samples);
if (client->nr_samples > 0) {
- /* fire another conversion for this */
-
- client->select_cb(client, 1);
+ /* fire another conversion for this client */
+ (client->select_cb)(client, 1);
s3c_adc_convert(adc);
} else {
- spin_lock(&adc->lock);
+ /* finish conversion for this client */
(client->select_cb)(client, 0);
- adc->cur = NULL;
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__,
+ client);
+ /* fire conversion for next client if any */
+ adc->cur = NULL;
s3c_adc_try(adc);
- spin_unlock(&adc->lock);
}
exit:
- if (cpu == TYPE_S3C64XX) {
+ if (cpu != TYPE_ADCV1) {
/* Clear ADC interrupt */
writel(0, adc->regs + S3C64XX_ADCCLRINT);
}
+
+ spin_unlock(&adc->lock);
+
return IRQ_HANDLED;
}
@@ -324,11 +378,12 @@ static int s3c_adc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct adc_device *adc;
struct resource *regs;
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
int ret;
unsigned tmp;
adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
- if (adc == NULL) {
+ if (unlikely(adc == NULL)) {
dev_err(dev, "failed to allocate adc_device\n");
return -ENOMEM;
}
@@ -338,35 +393,22 @@ static int s3c_adc_probe(struct platform_device *pdev)
adc->pdev = pdev;
adc->prescale = S3C2410_ADCCON_PRSCVL(49);
- adc->irq = platform_get_irq(pdev, 1);
- if (adc->irq <= 0) {
- dev_err(dev, "failed to get adc irq\n");
- ret = -ENOENT;
- goto err_alloc;
- }
-
- ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
- if (ret < 0) {
- dev_err(dev, "failed to attach adc irq\n");
- goto err_alloc;
- }
-
- adc->clk = clk_get(dev, "adc");
- if (IS_ERR(adc->clk)) {
+ adc->clk = clk_get(NULL, "adc");
+ if (unlikely(IS_ERR(adc->clk))) {
dev_err(dev, "failed to get adc clock\n");
ret = PTR_ERR(adc->clk);
- goto err_irq;
+ goto err_alloc;
}
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
+ if (unlikely(!regs)) {
dev_err(dev, "failed to find registers\n");
ret = -ENXIO;
goto err_clk;
}
adc->regs = ioremap(regs->start, resource_size(regs));
- if (!adc->regs) {
+ if (unlikely(!adc->regs)) {
dev_err(dev, "failed to map registers\n");
ret = -ENXIO;
goto err_clk;
@@ -374,13 +416,35 @@ static int s3c_adc_probe(struct platform_device *pdev)
clk_enable(adc->clk);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+
tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
- if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
- /* Enable 12-bit ADC resolution */
+
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1) {
tmp |= S3C64XX_ADCCON_RESSEL;
}
+ tmp |= S3C2410_ADCCON_STDBM;
writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->irq = platform_get_irq(pdev, 1);
+ if (unlikely(adc->irq <= 0)) {
+ dev_err(dev, "failed to get adc irq\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
+ ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
+ if (unlikely(ret < 0)) {
+ dev_err(dev, "failed to attach adc irq\n");
+ goto err_clk;
+ }
+
dev_info(dev, "attached adc driver\n");
platform_set_drvdata(pdev, adc);
@@ -391,9 +455,6 @@ static int s3c_adc_probe(struct platform_device *pdev)
err_clk:
clk_put(adc->clk);
- err_irq:
- free_irq(adc->irq, adc);
-
err_alloc:
kfree(adc);
return ret;
@@ -435,12 +496,24 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
static int s3c_adc_resume(struct platform_device *pdev)
{
struct adc_device *adc = platform_get_drvdata(pdev);
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
+ unsigned int tmp = 0;
clk_enable(adc->clk);
enable_irq(adc->irq);
- writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
- adc->regs + S3C2410_ADCCON);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ adc->regs -= 0x1000;
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1)
+ tmp |= S3C64XX_ADCCON_RESSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
return 0;
}
@@ -452,11 +525,17 @@ static int s3c_adc_resume(struct platform_device *pdev)
static struct platform_device_id s3c_adc_driver_ids[] = {
{
- .name = "s3c24xx-adc",
- .driver_data = TYPE_S3C24XX,
+ .name = "s3c24xx-adc",
+ .driver_data = TYPE_ADCV1,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_ADCV2,
+ }, {
+ .name = "samsung-adc-v3",
+ .driver_data = TYPE_ADCV3,
}, {
- .name = "s3c64xx-adc",
- .driver_data = TYPE_S3C64XX,
+ .name = "samsung-adc-v4",
+ .driver_data = TYPE_ADCV4,
},
{ }
};
diff --git aosp-v3.0/arch/arm/plat-samsung/clock.c smdk4210/arch/arm/plat-samsung/clock.c
index 7728928..40454d7 100644
--- aosp-v3.0/arch/arm/plat-samsung/clock.c
+++ smdk4210/arch/arm/plat-samsung/clock.c
@@ -27,7 +27,6 @@
*/
#include <linux/init.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
@@ -64,108 +63,55 @@ static LIST_HEAD(clocks);
*/
DEFINE_SPINLOCK(clocks_lock);
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
-{
- return 0;
-}
-
-static int dev_is_s3c_uart(struct device *dev)
+/* Global watchdog clock used by arch_wtd_reset() callback */
+struct clk *s3c2410_wdtclk;
+static int __init s3c_wdt_reset_init(void)
{
- struct platform_device **pdev = s3c24xx_uart_devs;
- int i;
- for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
- if (*pdev && dev == &(*pdev)->dev)
- return 1;
+ s3c2410_wdtclk = clk_get(NULL, "watchdog");
+ if (IS_ERR(s3c2410_wdtclk))
+ printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
return 0;
}
+arch_initcall(s3c_wdt_reset_init);
-/*
- * Serial drivers call get_clock() very early, before platform bus
- * has been set up, this requires a special check to let them get
- * a proper clock
- */
-
-static int dev_is_platform_device(struct device *dev)
-{
- return dev->bus == &platform_bus_type ||
- (dev->bus == NULL && dev_is_s3c_uart(dev));
-}
-
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || !dev_is_platform_device(dev))
- idno = -1;
- else
- idno = to_platform_device(dev)->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;
- }
- }
-
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
-
- 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;
- }
- }
- }
-
- spin_unlock(&clocks_lock);
- return clk;
-}
+/* enable and disable calls for use with the clk struct */
-void clk_put(struct clk *clk)
+static int clk_null_enable(struct clk *clk, int enable)
{
- module_put(clk->owner);
+ return 0;
}
int clk_enable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return -EINVAL;
clk_enable(clk->parent);
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((clk->usage++) == 0)
(clk->enable)(clk, 1);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
void clk_disable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((--clk->usage) == 0)
(clk->enable)(clk, 0);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
clk_disable(clk->parent);
}
@@ -197,6 +143,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ unsigned long flags;
int ret;
if (IS_ERR(clk))
@@ -212,9 +159,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (clk->ops == NULL || clk->ops->set_rate == NULL)
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
ret = (clk->ops->set_rate)(clk, rate);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
@@ -226,23 +173,22 @@ struct clk *clk_get_parent(struct clk *clk)
int clk_set_parent(struct clk *clk, struct clk *parent)
{
+ unsigned long flags;
int ret = 0;
if (IS_ERR(clk))
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if (clk->ops && clk->ops->set_parent)
ret = (clk->ops->set_parent)(clk, parent);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
EXPORT_SYMBOL(clk_enable);
EXPORT_SYMBOL(clk_disable);
EXPORT_SYMBOL(clk_get_rate);
@@ -343,17 +289,20 @@ struct clk s3c24xx_uclk = {
*/
int s3c24xx_register_clock(struct clk *clk)
{
+ unsigned long flags;
+
if (clk->enable == NULL)
clk->enable = clk_null_enable;
- /* add to the list of available clocks */
+ /* fill up the clk_lookup structure and register it*/
+ clk->lookup.dev_id = clk->devname;
+ clk->lookup.con_id = clk->name;
+ clk->lookup.clk = clk;
+ clkdev_add(&clk->lookup);
- /* Quick check to see if this clock has already been registered. */
- BUG_ON(clk->list.prev != clk->list.next);
-
- spin_lock(&clocks_lock);
- list_add(&clk->list, &clocks);
- spin_unlock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
+ list_add_tail(&clk->list, &clocks);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
@@ -458,15 +407,12 @@ static struct dentry *clk_debugfs_root;
static int clk_debugfs_register_one(struct clk *c)
{
int err;
- struct dentry *d, *child, *child_tmp;
+ struct dentry *d;
struct clk *pa = c->parent;
char s[255];
char *p = s;
- p += sprintf(p, "%s", c->name);
-
- if (c->id >= 0)
- sprintf(p, ":%d", c->id);
+ p += sprintf(p, "%s", c->devname ?: c->name);
d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
if (!d)
@@ -488,10 +434,7 @@ static int clk_debugfs_register_one(struct clk *c)
return 0;
err_out:
- d = c->dent;
- list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
- debugfs_remove(child);
- debugfs_remove(c->dent);
+ debugfs_remove_recursive(c->dent);
return err;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-adc.c smdk4210/arch/arm/plat-samsung/dev-adc.c
index 9d903d4..d9d0357 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-adc.c
+++ smdk4210/arch/arm/plat-samsung/dev-adc.c
@@ -23,12 +23,14 @@
static struct resource s3c_adc_resource[] = {
[0] = {
.start = SAMSUNG_PA_ADC,
- .end = SAMSUNG_PA_ADC + SZ_256 - 1,
+ .end = SAMSUNG_PA_ADC + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+#if defined(CONFIG_TOUCHSCREEN_S3C2410)
.start = IRQ_TC,
.end = IRQ_TC,
+#endif
.flags = IORESOURCE_IRQ,
},
[2] = {
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-asocdma.c smdk4210/arch/arm/plat-samsung/dev-asocdma.c
index a068c4f..aabee5e 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-asocdma.c
+++ smdk4210/arch/arm/plat-samsung/dev-asocdma.c
@@ -23,3 +23,17 @@ struct platform_device samsung_asoc_dma = {
}
};
EXPORT_SYMBOL(samsung_asoc_dma);
+
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+static u64 audio_idmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_idma = {
+ .name = "samsung-audio-idma",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_idmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_idma);
+#endif
\ No newline at end of file
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-fb.c smdk4210/arch/arm/plat-samsung/dev-fb.c
index bf60204..49a1362 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-fb.c
+++ smdk4210/arch/arm/plat-samsung/dev-fb.c
@@ -58,16 +58,6 @@ struct platform_device s3c_device_fb = {
void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
{
- struct s3c_fb_platdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_fb.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s3c_device_fb);
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc.c smdk4210/arch/arm/plat-samsung/dev-hsmmc.c
index db7a65c..e5ee2df 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc.c
+++ smdk4210/arch/arm/plat-samsung/dev-hsmmc.c
@@ -65,7 +65,10 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc1.c smdk4210/arch/arm/plat-samsung/dev-hsmmc1.c
index 2497321..40160c6 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc1.c
+++ smdk4210/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -65,6 +65,7 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
if (pd->max_width)
set->max_width = pd->max_width;
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc2.c smdk4210/arch/arm/plat-samsung/dev-hsmmc2.c
index f60aedb..27bd631 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc2.c
+++ smdk4210/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -20,6 +20,7 @@
#include <mach/map.h>
#include <plat/sdhci.h>
#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
#define S3C_SZ_HSMMC (0x1000)
@@ -65,8 +66,15 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
+ /* if it uses eint as cd pin, pull up/down value of eint port
+ should be NONE */
+ if (pd->ext_cd_gpio)
+ s3c_gpio_setpull(pd->ext_cd_gpio, S3C_GPIO_PULL_NONE);
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc3.c smdk4210/arch/arm/plat-samsung/dev-hsmmc3.c
index ede776f..1973ef4 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-hsmmc3.c
+++ smdk4210/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -69,6 +69,13 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
+#ifdef CONFIG_MACH_PX
+ set->ext_pdev = pd->ext_pdev;
+#endif
if (pd->max_width)
set->max_width = pd->max_width;
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-hwmon.c smdk4210/arch/arm/plat-samsung/dev-hwmon.c
index b3ffb95..c91a79c 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-hwmon.c
+++ smdk4210/arch/arm/plat-samsung/dev-hwmon.c
@@ -27,16 +27,6 @@ struct platform_device s3c_device_hwmon = {
void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
{
- struct s3c_hwmon_pdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_hwmon.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
+ &s3c_device_hwmon);
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c0.c smdk4210/arch/arm/plat-samsung/dev-i2c0.c
index 3a601c1..1edd343 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c0.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c0.c
@@ -48,10 +48,10 @@ struct platform_device s3c_device_i2c0 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+struct s3c2410_platform_i2c default_i2c_data __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .frequency = 100*1000,
+ .frequency = 400*1000,
.sda_delay = 100,
};
@@ -60,13 +60,11 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
struct s3c2410_platform_i2c *npd;
if (!pd)
- pd = &default_i2c_data0;
+ pd = &default_i2c_data;
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c0);
- s3c_device_i2c0.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c0_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c1.c smdk4210/arch/arm/plat-samsung/dev-i2c1.c
index 858ee2a..3b7c7be 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c1.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c1.c
@@ -44,26 +44,18 @@ struct platform_device s3c_device_i2c1 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
- .flags = 0,
- .bus_num = 1,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data1;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 1;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c1);
- s3c_device_i2c1.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c2.c smdk4210/arch/arm/plat-samsung/dev-i2c2.c
index ff4ba69..07e9fd0 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c2.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c2.c
@@ -45,26 +45,18 @@ struct platform_device s3c_device_i2c2 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
- .flags = 0,
- .bus_num = 2,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data2;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 2;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c2_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c2);
- s3c_device_i2c2.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c2_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c3.c smdk4210/arch/arm/plat-samsung/dev-i2c3.c
index 8586a10..d48efa9 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c3.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c3.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c3 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
- .flags = 0,
- .bus_num = 3,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data3;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 3;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c3);
- s3c_device_i2c3.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c4.c smdk4210/arch/arm/plat-samsung/dev-i2c4.c
index df2159e..07e2644 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c4.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c4.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c4 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
- .flags = 0,
- .bus_num = 4,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data4;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 4;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c4);
- s3c_device_i2c4.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c5.c smdk4210/arch/arm/plat-samsung/dev-i2c5.c
index 0499c2c..f496557 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c5.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c5.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c5 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
- .flags = 0,
- .bus_num = 5,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data5;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 5;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c5);
- s3c_device_i2c5.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c6.c smdk4210/arch/arm/plat-samsung/dev-i2c6.c
index 4083108..141d799 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c6.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c6.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c6 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
- .flags = 0,
- .bus_num = 6,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data6;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 6;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c6);
- s3c_device_i2c6.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-i2c7.c smdk4210/arch/arm/plat-samsung/dev-i2c7.c
index 1182451..9dddcd1 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-i2c7.c
+++ smdk4210/arch/arm/plat-samsung/dev-i2c7.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c7 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
- .flags = 0,
- .bus_num = 7,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data7;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 7;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c7);
- s3c_device_i2c7.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-keypad.c smdk4210/arch/arm/plat-samsung/dev-keypad.c
index 677c2d7..385051f 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-keypad.c
+++ smdk4210/arch/arm/plat-samsung/dev-keypad.c
@@ -32,7 +32,11 @@ static struct resource samsung_keypad_resources[] = {
};
struct platform_device samsung_device_keypad = {
+ #if defined(CONFIG_MACH_GRANDE) || defined(CONFIG_MACH_IRON)
+ .name = "grande_3x4_keypad",
+ #else
.name = "samsung-keypad",
+ #endif
.id = -1,
.num_resources = ARRAY_SIZE(samsung_keypad_resources),
.resource = samsung_keypad_resources,
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-nand.c smdk4210/arch/arm/plat-samsung/dev-nand.c
index 6927ae8..b8e30ec 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-nand.c
+++ smdk4210/arch/arm/plat-samsung/dev-nand.c
@@ -91,11 +91,10 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
* time then there is little chance the system is going to run.
*/
- npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
- if (!npd) {
- printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+ npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
+ &s3c_device_nand);
+ if (!npd)
return;
- }
/* now see if we need to copy any of the nand set data */
@@ -123,6 +122,4 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
to++;
}
}
-
- s3c_device_nand.dev.platform_data = npd;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-pwm.c smdk4210/arch/arm/plat-samsung/dev-pwm.c
index dab47b0..cda8e47 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-pwm.c
+++ smdk4210/arch/arm/plat-samsung/dev-pwm.c
@@ -20,6 +20,7 @@
#include <mach/irqs.h>
#include <plat/devs.h>
+#include <mach/gpio.h>
#define TIMER_RESOURCE_SIZE (1)
@@ -32,22 +33,88 @@
} \
}
-#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
- .name = "s3c24xx-pwm", \
- .id = _tmr_no, \
- .num_resources = TIMER_RESOURCE_SIZE, \
- .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+#define DEFINE_S3C_TIMER(_tmr_no, _irq, _plat_data) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+ .dev = { \
+ .platform_data = _plat_data, \
+ }
+
+#define GPD0_0_TOUT (0x2 << 0)
+#ifdef CONFIG_FB_MDNIE_PWM
+#define GPD0_1_TOUT (0x3 << 4)
+#else
+#define GPD0_1_TOUT (0x2 << 4)
+#endif
+#define GPD0_2_TOUT (0x2 << 8)
+#define GPD0_3_TOUT (0x2 << 12)
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
*/
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ int gpio_no;
+ const char *gpio_name;
+ int gpio_set_value;
+};
+
+struct s3c_pwm_pdata pwm_data[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .gpio_no = EXYNOS5_GPB2(0),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(1),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(2),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(3),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#else
+ {
+ .gpio_no = EXYNOS4_GPD0(0),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(1),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(2),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(3),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#endif
+};
+
struct platform_device s3c_device_timer[] = {
- [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
- [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
- [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
- [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
- [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+ [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0, &pwm_data[0]) },
+ [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1, &pwm_data[1]) },
+ [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2, &pwm_data[2]) },
+ [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3, &pwm_data[3]) },
+ [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4, &pwm_data[4]) },
};
EXPORT_SYMBOL(s3c_device_timer);
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-ts.c smdk4210/arch/arm/plat-samsung/dev-ts.c
index 3e4bd81..f9af090 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-ts.c
+++ smdk4210/arch/arm/plat-samsung/dev-ts.c
@@ -38,23 +38,13 @@ static struct resource s3c_ts_resource[] = {
struct platform_device s3c_device_ts = {
.name = "s3c64xx-ts",
- .id = -1,
+ .id = 0,
.num_resources = ARRAY_SIZE(s3c_ts_resource),
.resource = s3c_ts_resource,
};
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
{
- struct s3c2410_ts_mach_info *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ts.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
+ &s3c_device_ts);
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-usb.c smdk4210/arch/arm/plat-samsung/dev-usb.c
index 0e0a3bf..33fbaa9 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-usb.c
+++ smdk4210/arch/arm/plat-samsung/dev-usb.c
@@ -60,11 +60,6 @@ EXPORT_SYMBOL(s3c_device_ohci);
*/
void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
{
- struct s3c2410_hcd_info *npd;
-
- npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ohci.dev.platform_data = npd;
+ s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
+ &s3c_device_ohci);
}
diff --git aosp-v3.0/arch/arm/plat-samsung/dev-wdt.c smdk4210/arch/arm/plat-samsung/dev-wdt.c
index 019b5b8..c9d8f2c 100644
--- aosp-v3.0/arch/arm/plat-samsung/dev-wdt.c
+++ smdk4210/arch/arm/plat-samsung/dev-wdt.c
@@ -21,7 +21,7 @@
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C_PA_WDT,
- .end = S3C_PA_WDT + SZ_1K,
+ .end = S3C_PA_WDT + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git aosp-v3.0/arch/arm/plat-samsung/gpio-config.c smdk4210/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..712ec09 100644
--- aosp-v3.0/arch/arm/plat-samsung/gpio-config.c
+++ smdk4210/arch/arm/plat-samsung/gpio-config.c
@@ -429,3 +429,99 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
}
EXPORT_SYMBOL(s5p_gpio_set_drvstr);
#endif /* CONFIG_S5P_GPIO_DRVSTR */
+
+s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_cfg;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ pd_cfg = __raw_readl(reg);
+ pd_cfg = pd_cfg >> shift;
+ pd_cfg &= 0x3;
+
+ return (__force s5p_gpio_pd_cfg_t)pd_cfg;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_cfg);
+
+int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_cfg << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_cfg);
+
+s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_pull;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ pd_pull = __raw_readl(reg);
+ pd_pull = pd_pull >> shift;
+ pd_pull &= 0x3;
+
+ return (__force s5p_gpio_pd_pull_t)pd_pull;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_pull);
+
+int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_pull << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_pull);
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/adc.h smdk4210/arch/arm/plat-samsung/include/plat/adc.h
index b258a08..449f409 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/adc.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/adc.h
@@ -17,7 +17,8 @@
struct s3c_adc_client;
extern int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples);
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake);
extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/audio.h smdk4210/arch/arm/plat-samsung/include/plat/audio.h
index a0826ed..bfee644 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/audio.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/audio.h
@@ -36,6 +36,10 @@ struct samsung_i2s {
*/
#define QUIRK_NO_MUXPSR (1 << 2)
#define QUIRK_NEED_RSTCLR (1 << 3)
+/* If the idma will be enabled */
+#define QUIRK_ENABLED_IDMA (1 << 4)
+/* If the srp will be enabled */
+#define QUIRK_ENABLED_SRP (1 << 5)
/* Quirks of the I2S controller */
u32 quirks;
@@ -56,3 +60,5 @@ struct s3c_audio_pdata {
struct samsung_i2s i2s;
} type;
};
+
+extern void __init exynos4_i2sv3_setup_resource(void);
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/clock.h smdk4210/arch/arm/plat-samsung/include/plat/clock.h
index 983c578..76198a7 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/clock.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/clock.h
@@ -9,7 +9,11 @@
* published by the Free Software Foundation.
*/
+#ifndef __ASM_PLAT_CLOCK_H
+#define __ASM_PLAT_CLOCK_H __FILE__
+
#include <linux/spinlock.h>
+#include <linux/clkdev.h>
struct clk;
@@ -40,6 +44,7 @@ struct clk {
struct module *owner;
struct clk *parent;
const char *name;
+ const char *devname;
int id;
int usage;
unsigned long rate;
@@ -47,6 +52,7 @@ struct clk {
struct clk_ops *ops;
int (*enable)(struct clk *, int enable);
+ struct clk_lookup lookup;
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
#endif
@@ -78,6 +84,7 @@ extern struct clk clk_h2;
extern struct clk clk_27m;
extern struct clk clk_48m;
extern struct clk clk_xusbxti;
+extern struct clk clk_xxti;
extern int clk_default_setrate(struct clk *clk, unsigned long rate);
extern struct clk_ops clk_ops_def_setrate;
@@ -118,3 +125,8 @@ extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
extern void s3c_pwmclk_init(void);
+/* Global watchdog clock used by arch_wtd_reset() callback */
+
+extern struct clk *s3c2410_wdtclk;
+
+#endif /* __ASM_PLAT_CLOCK_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/cpu.h smdk4210/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..8699823 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/cpu.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/cpu.h
@@ -1,9 +1,12 @@
/* linux/arch/arm/plat-samsung/include/plat/cpu.h
*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * Header file for S3C24XX CPU support
+ * Header file for Samsung CPU 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
@@ -15,6 +18,140 @@
#ifndef __SAMSUNG_PLAT_CPU_H
#define __SAMSUNG_PLAT_CPU_H
+extern unsigned long samsung_cpu_id;
+
+#define S3C24XX_CPU_ID 0x32400000
+#define S3C24XX_CPU_MASK 0xFFF00000
+
+#define S3C6400_CPU_ID 0x36400000
+#define S3C6410_CPU_ID 0x36410000
+#define S3C64XX_CPU_ID (S3C6400_CPU_ID & S3C6410_CPU_ID)
+#define S3C64XX_CPU_MASK 0x1FF40000
+
+#define S5P6440_CPU_ID 0x56440000
+#define S5P6450_CPU_ID 0x36450000
+#define S5P64XX_CPU_MASK 0x1FF40000
+
+#define S5PC100_CPU_ID 0x43100000
+#define S5PC100_CPU_MASK 0xFFFFF000
+
+#define S5PV210_CPU_ID 0x43110000
+#define S5PV210_CPU_MASK 0xFFFFF000
+
+#define EXYNOS4210_CPU_ID 0x43210000
+#define EXYNOS4212_CPU_ID 0x43220000
+#define EXYNOS4412_CPU_ID 0xE4412200
+#define EXYNOS5210_CPU_ID 0x43510000
+#define EXYNOS5250_CPU_ID 0x43520000
+#define EXYNOS_CPU_MASK 0xFFFE0000
+
+#define IS_SAMSUNG_CPU(name, id, mask) \
+static inline int is_samsung_##name(void) \
+{ \
+ return ((samsung_cpu_id & mask) == (id & mask)); \
+}
+
+IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
+IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5210, EXYNOS5210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_CPU_ID, EXYNOS_CPU_MASK)
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
+ defined(CONFIG_CPU_S3C2443)
+# define soc_is_s3c24xx() is_samsung_s3c24xx()
+#else
+# define soc_is_s3c24xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c64xx() is_samsung_s3c64xx()
+#else
+# define soc_is_s3c64xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6440)
+# define soc_is_s5p6440() is_samsung_s5p6440()
+#else
+# define soc_is_s5p6440() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6450)
+# define soc_is_s5p6450() is_samsung_s5p6450()
+#else
+# define soc_is_s5p6450() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PC100)
+# define soc_is_s5pc100() is_samsung_s5pc100()
+#else
+# define soc_is_s5pc100() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PV210)
+# define soc_is_s5pv210() is_samsung_s5pv210()
+#else
+# define soc_is_s5pv210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+# define soc_is_exynos4210() is_samsung_exynos4210()
+#else
+# define soc_is_exynos4210() 0
+#endif
+
+#define EXYNOS4210_REV_0 (0x0)
+#define EXYNOS4210_REV_1_0 (0x10)
+#define EXYNOS4210_REV_1_1 (0x11)
+#define EXYNOS4210_REV_1_2 (0x12)
+
+#if defined(CONFIG_CPU_EXYNOS4212)
+# define soc_is_exynos4212() is_samsung_exynos4212()
+#else
+# define soc_is_exynos4212() 0
+#endif
+
+#define EXYNOS4212_REV_0 (0x0)
+#define EXYNOS4212_REV_1_0 (0x10)
+
+#if defined(CONFIG_CPU_EXYNOS4412)
+# define soc_is_exynos4412() is_samsung_exynos4412()
+#else
+# define soc_is_exynos4412() 0
+#endif
+
+#define EXYNOS4412_REV_0 (0x0)
+#define EXYNOS4412_REV_0_1 (0x01)
+#define EXYNOS4412_REV_1_0 (0x10)
+#define EXYNOS4412_REV_1_1 (0x11)
+#define EXYNOS4412_REV_2_0 (0x20)
+
+#if defined(CONFIG_CPU_EXYNOS5210)
+# define soc_is_exynos5210() is_samsung_exynos5210()
+#else
+# define soc_is_exynos5210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS5250)
+# define soc_is_exynos5250() is_samsung_exynos5250()
+# define soc_is_exynos5250_rev1 (soc_is_exynos5250() && \
+ samsung_rev() >= EXYNOS5250_REV_1_0)
+#else
+# define soc_is_exynos5250() 0
+# define soc_is_exynos5250_rev1 0
+#endif
+
+#define EXYNOS5250_REV_0 (0x0)
+#define EXYNOS5250_REV_1_0 (0x10)
+
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
@@ -55,6 +192,12 @@ extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
extern void s5p_init_io(struct map_desc *mach_desc,
int size, void __iomem *cpuid_addr);
+extern void s3c24xx_init_cpu(void);
+extern void s3c64xx_init_cpu(void);
+extern void s5p_init_cpu(void __iomem *cpuid_addr);
+
+extern unsigned int samsung_rev(void);
+
extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
@@ -88,6 +231,7 @@ extern struct sysdev_class s3c64xx_sysclass;
extern struct sysdev_class s5p64x0_sysclass;
extern struct sysdev_class s5pv210_sysclass;
extern struct sysdev_class exynos4_sysclass;
+extern struct sysdev_class exynos5_sysclass;
extern void (*s5pc1xx_idle)(void);
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/devs.h smdk4210/arch/arm/plat-samsung/include/plat/devs.h
index e3b31c2..1321d7b 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/devs.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/devs.h
@@ -17,6 +17,7 @@
#define __PLAT_DEVS_H __FILE__
#include <linux/platform_device.h>
+#include <linux/platform_data/exynos_usb3_drd.h>
struct s3c24xx_uart_resources {
struct resource *resources;
@@ -40,6 +41,7 @@ extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
extern struct platform_device samsung_asoc_dma;
+extern struct platform_device samsung_asoc_idma;
extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
@@ -47,8 +49,16 @@ extern struct platform_device s3c64xx_device_pcm1;
extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_ts1;
extern struct platform_device s3c_device_fb;
+#ifdef CONFIG_FB_S5P_EXTDSP
+extern struct platform_device s3c_device_extdsp;
+#endif
+extern struct platform_device s5p_device_fimd0;
+extern struct platform_device s5p_device_fimd1;
+extern struct platform_device s5p_device_mipi_dsim0;
+extern struct platform_device s5p_device_mipi_dsim1;
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -60,6 +70,7 @@ extern struct platform_device s3c_device_i2c4;
extern struct platform_device s3c_device_i2c5;
extern struct platform_device s3c_device_i2c6;
extern struct platform_device s3c_device_i2c7;
+extern struct platform_device s5p_device_i2c_hdmiphy;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi;
@@ -69,6 +80,7 @@ extern struct platform_device s3c_device_hsmmc0;
extern struct platform_device s3c_device_hsmmc1;
extern struct platform_device s3c_device_hsmmc2;
extern struct platform_device s3c_device_hsmmc3;
+extern struct platform_device s3c_device_mshci;
extern struct platform_device s3c_device_cfcon;
extern struct platform_device s3c_device_spi0;
@@ -81,6 +93,9 @@ extern struct platform_device s5pv210_device_spi0;
extern struct platform_device s5pv210_device_spi1;
extern struct platform_device s5p64x0_device_spi0;
extern struct platform_device s5p64x0_device_spi1;
+extern struct platform_device exynos_device_spi0;
+extern struct platform_device exynos_device_spi1;
+extern struct platform_device exynos_device_spi2;
extern struct platform_device s3c_device_hwmon;
@@ -92,6 +107,13 @@ 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_usb_hsotg;
+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;
+#ifdef CONFIG_USB_ANDROID_RNDIS
+extern struct platform_device s3c_device_rndis;
+#endif
+extern struct platform_device s5p_device_usbswitch;
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_pcm0;
@@ -101,17 +123,45 @@ extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2;
extern struct platform_device s5pv210_device_spdif;
-
-extern struct platform_device exynos4_device_ac97;
-extern struct platform_device exynos4_device_pcm0;
-extern struct platform_device exynos4_device_pcm1;
-extern struct platform_device exynos4_device_pcm2;
-extern struct platform_device exynos4_device_i2s0;
-extern struct platform_device exynos4_device_i2s1;
-extern struct platform_device exynos4_device_i2s2;
-extern struct platform_device exynos4_device_spdif;
+extern struct platform_device s5pv210_device_cpufreq;
+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 exynos_device_ac97;
+extern struct platform_device exynos_device_pcm0;
+extern struct platform_device exynos_device_pcm1;
+extern struct platform_device exynos_device_pcm2;
+extern struct platform_device exynos_device_i2s0;
+extern struct platform_device exynos_device_i2s1;
+extern struct platform_device exynos_device_i2s2;
+extern struct platform_device exynos_device_spdif;
+extern struct platform_device exynos_device_srp;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_ahci;
+extern struct platform_device exynos_device_pdma0;
+extern struct platform_device exynos_device_pdma1;
+extern struct platform_device exynos_device_mdma;
+extern struct platform_device exynos_device_dwmci;
+extern struct platform_device exynos_device_dwmci0;
+extern struct platform_device exynos_device_dwmci1;
+extern struct platform_device exynos_device_dwmci2;
+extern struct platform_device exynos_device_dwmci3;
+extern struct platform_device exynos_device_flite0;
+extern struct platform_device exynos_device_flite1;
+extern struct platform_device exynos4_device_c2c;
+extern struct platform_device exynos_device_flite2;
+extern struct platform_device exynos4_device_fimc_is;
+extern struct platform_device exynos5_device_fimc_is;
+extern struct platform_device exynos5_device_pd[];
+extern struct platform_device exynos5_device_gsc0;
+extern struct platform_device exynos5_device_gsc1;
+extern struct platform_device exynos5_device_gsc2;
+extern struct platform_device exynos5_device_gsc3;
+extern struct platform_device exynos5_device_ahci;
+extern struct platform_device exynos_device_c2c;
+extern struct platform_device exynos_device_ss_udc;
+extern struct platform_device exynos_device_xhci;
extern struct platform_device s5p6440_device_pcm;
extern struct platform_device s5p6440_device_iis;
@@ -130,18 +180,57 @@ extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad;
-
+#ifndef CONFIG_VIDEO_FIMC
extern struct platform_device s5p_device_fimc0;
extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2;
extern struct platform_device s5p_device_fimc3;
-
+#else
+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_fimc3;
+#endif
+#ifndef CONFIG_VIDEO_FIMC_MIPI
extern struct platform_device s5p_device_mipi_csis0;
extern struct platform_device s5p_device_mipi_csis1;
+#else
+extern struct platform_device s3c_device_csis0;
+extern struct platform_device s3c_device_csis1;
+#endif
+extern struct platform_device s5p_device_dp;
+
+extern struct platform_device s5p_device_jpeg;
+extern struct platform_device s5p_device_tvout;
+extern struct platform_device s5p_device_cec;
+extern struct platform_device s5p_device_hpd;
+extern struct platform_device s5p_device_ace;
+extern struct platform_device s5p_device_fimg2d;
+extern struct platform_device exynos_device_rotator;
extern struct platform_device s5p_device_ehci;
+extern struct platform_device s5p_device_ohci;
+#ifdef CONFIG_USB_HOST_NOTIFY
+extern struct platform_device host_notifier_device;
+#endif
-extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device exynos_device_sysmmu[];
+
+extern struct platform_device s5p_device_mfc;
+extern struct platform_device s5p_device_mipi_dsim;
+extern struct platform_device s5p_device_dsim;
+
+extern struct platform_device s5p_device_hdmi;
+extern struct platform_device s5p_device_mixer;
+extern struct platform_device s5p_device_sdo;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+extern struct platform_device s5p_device_dsim;
+#endif
+
+#ifdef CONFIG_SENSORS_EXYNOS4_TMU
+extern struct platform_device exynos4_device_tmu;
+#endif
/* s3c2440 specific devices */
@@ -152,6 +241,13 @@ extern struct platform_device s3c_device_ac97;
#endif
+#if defined(CONFIG_VIDEO_TSI)
+extern struct platform_device s3c_device_tsi;
+#endif
+
+extern void exynos_ss_udc_set_platdata(struct exynos_usb3_drd_pdata *pd);
+extern void exynos_xhci_set_platdata(struct exynos_usb3_drd_pdata *pd);
+
/**
* s3c_set_platdata() - helper for setting platform data
* @pd: The default platform data for this device.
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/dma.h smdk4210/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7..816d505 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/dma.h
+++ smdk4210/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
@@ -96,8 +98,18 @@ extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
* drained before the buffer is given to the DMA system.
*/
-extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size);
+#define s3c2410_dma_enqueue(id, token, addr, size) \
+ s3c2410_dma_enqueue_ring(id, token, addr, size, 0)
+
+/* s3c2410_dma_enqueue_ring
+ *
+ * place the given buffer onto the queue of operations for the channel.
+ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+ * drained before the buffer is given to the DMA system.
+*/
+
+extern int s3c2410_dma_enqueue_ring(enum dma_ch channel, void *id,
+ dma_addr_t data, int size, int numofblock);
/* s3c2410_dma_config
*
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/fb-core.h smdk4210/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..4335840 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/fb-core.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,25 @@ static inline void s3c_fb_setname(char *name)
#endif
}
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+ case 0:
+ s5p_device_fimd0.name = name;
+ break;
+#endif
+
+#ifdef CONFIG_S5P_DEV_FIMD1
+ case 1:
+ s5p_device_fimd1.name = name;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+ break;
+ }
+}
+
#endif /* __ASM_PLAT_FB_CORE_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/fb.h smdk4210/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..2e1813f 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/fb.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,8 @@
#ifndef __PLAT_S3C_FB_H
#define __PLAT_S3C_FB_H __FILE__
+#include <plat/gpio-cfg.h>
+
/* S3C_FB_MAX_WIN
* Set to the maximum number of windows that any of the supported hardware
* can use. Since the platform data uses this for an array size, having it
@@ -22,11 +24,28 @@
*/
#define S3C_FB_MAX_WIN (5)
+#if defined(CONFIG_MACH_P11) || defined(CONFIG_MACH_P10)
+/* IOCTL commands */
+#define S3CFB_WIN_POSITION _IOW('F', 203, \
+ struct s3c_fb_user_window)
+#define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204, \
+ struct s3c_fb_user_plane_alpha)
+#define S3CFB_WIN_SET_CHROMA _IOW('F', 205, \
+ struct s3c_fb_user_chroma)
+#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
+
+#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, \
+ struct s3c_fb_user_ion_client)
+#define S3CFB_PAN_DISPLAY_INDEX _IOW('F', 209, __u32)
+
+#endif
/**
* 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.
+ * @width: The width of display in mm
+ * @height: The height of display in mm
*/
struct s3c_fb_pd_win {
struct fb_videomode win_mode;
@@ -35,6 +54,8 @@ struct s3c_fb_pd_win {
unsigned short max_bpp;
unsigned short virtual_x;
unsigned short virtual_y;
+ unsigned short width;
+ unsigned short height;
};
/**
@@ -74,6 +95,22 @@ struct s3c_fb_platdata {
extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
/**
+ * s5p_fimd0_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 s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s5p_fimd1_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 s5p_fimd1_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.
@@ -94,4 +131,30 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
*/
extern void s5pv210_fb_gpio_setup_24bpp(void);
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
+/**
+ * exynos4_fimd_cfg_gpios() - Exynos4 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void exynos4_fimd_cfg_gpios(unsigned int base, unsigned int nr,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr);
+
+/**
+ * exynos4_fimd0_setup_clock() = Exynos4 setup function for parent clock.
+ * @dev: device pointer
+ * @parent: parent clock used for LCD pixel clock
+ * @clk_rate: clock rate for parent clock
+ */
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate);
+
+int __init exynos4_fimd_setup_clock(struct device *dev, const char *bus_clk,
+ const char *parent, unsigned long clk_rate);
#endif /* __PLAT_S3C_FB_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/gpio-cfg.h smdk4210/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb..943789c 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -26,6 +26,8 @@
typedef unsigned int __bitwise__ s3c_gpio_pull_t;
typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_cfg_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_pull_t;
/* forward declaration if gpio-core.h hasn't been included */
struct s3c_gpio_chip;
@@ -125,12 +127,30 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
*
* These values control the state of the weak pull-{up,down} resistors
* available on most pins on the S3C series. Not all chips support both
- * up or down settings, and it may be dependent on the chip that is being
+ * up or down settings, and it may be dependant on the chip that is being
* used to whether the particular mode is available.
*/
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x03)
+#else
#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02)
+#endif
+
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+/* need to move to mach/gpio.h */
+#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)
+
+#define S3C_GPIO_SETPIN_ZERO 0
+#define S3C_GPIO_SETPIN_ONE 1
+#define S3C_GPIO_SETPIN_NONE 2
+#endif
/**
* s3c_gpio_setpull() - set the state of a gpio pin pull resistor
@@ -207,6 +227,65 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
*/
extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+/* Define values for the power down configuration available for each gpio pin.
+ *
+ * These values control the state of the power down configuration resistors
+ * available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_OUTPUT0 ((__force s5p_gpio_pd_cfg_t)0x00)
+#define S5P_GPIO_PD_OUTPUT1 ((__force s5p_gpio_pd_cfg_t)0x01)
+#define S5P_GPIO_PD_INPUT ((__force s5p_gpio_pd_cfg_t)0x02)
+#define S5P_GPIO_PD_PREV_STATE ((__force s5p_gpio_pd_cfg_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_cfg() - set the configuration of a gpio power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_cfg: The configuration for the pwer down mode configuration register.
+ *
+ * This function sets the configuration of the power down mode resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested power down mode.
+ *
+*/
+extern int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg);
+
+/**
+ * s5p_gpio_get_pd_cfg() - get the power down mode configuration of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power down mode resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin);
+
+/* Define values for the power down pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the power down mode pull-{up,down}
+ * resistors available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_UPDOWN_DISABLE ((__force s5p_gpio_pd_pull_t)0x00)
+#define S5P_GPIO_PD_DOWN_ENABLE ((__force s5p_gpio_pd_pull_t)0x01)
+#define S5P_GPIO_PD_UP_ENABLE ((__force s5p_gpio_pd_pull_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_pull() - set the pull-{up,down} of a gpio pin power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_pull: The configuration for the power down mode pull resistor.
+ *
+ * This function sets the configuration of the pull-{up,down} resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested pull setting.
+ *
+*/
+extern int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull);
+
+/**
+ * s5p_gpio_get_pd_pull() - get the power down pull resistor config of gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power mode pull resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin);
+
/**
* s5p_register_gpio_interrupt() - register interrupt support for a gpio group
* @pin: The pin number from the group to be registered
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/gpio-core.h smdk4210/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf..792fdb0 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -67,7 +67,8 @@ struct s3c_gpio_chip {
void __iomem *base;
int irq_base;
int group;
- spinlock_t lock;
+ unsigned int eint_offset;
+ spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
@@ -116,6 +117,8 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
*/
extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
int nr_chips);
+extern void samsung_gpiolib_add_4bit_chips_no_pm(struct s3c_gpio_chip *chip,
+ int nr_chips);
extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
int nr_chips);
extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
@@ -141,9 +144,9 @@ extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
#ifdef CONFIG_S3C_GPIO_TRACK
extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
{
- return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+ return (pin < S3C_GPIO_END) ? s3c_gpios[pin] : NULL;
}
#else
/* machine specific code should provide s3c_gpiolib_getchip */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/iic.h smdk4210/arch/arm/plat-samsung/include/plat/iic.h
index 1543da8..51d52e7 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/iic.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/iic.h
@@ -60,6 +60,7 @@ extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
@@ -71,4 +72,6 @@ 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 struct s3c2410_platform_i2c default_i2c_data;
+
#endif /* __ASM_ARCH_IIC_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/keypad.h smdk4210/arch/arm/plat-samsung/include/plat/keypad.h
index b59a648..997220f 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/keypad.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/keypad.h
@@ -14,9 +14,13 @@
#define __PLAT_SAMSUNG_KEYPAD_H
#include <linux/input/matrix_keypad.h>
-
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+#define SAMSUNG_MAX_ROWS 14
+#define SAMSUNG_MAX_COLS 8
+#else
#define SAMSUNG_MAX_ROWS 8
#define SAMSUNG_MAX_COLS 8
+#endif
/**
* struct samsung_keypad_platdata - Platform device data for Samsung Keypad.
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/map-base.h smdk4210/arch/arm/plat-samsung/include/plat/map-base.h
index 3ffac4d..ec28c99 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/map-base.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,15 +14,15 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF6000000 upwards, trying to use as
- * little of the VA space as possible so vmalloc and friends have a
- * better chance of getting memory.
+/* Fit all our registers in at CONFIG_S3C_BASE_ADDR upwards, trying to
+ * use as little of the VA space as possible so vmalloc and friends
+ * have a better chance of getting memory.
*
* we try to ensure stuff like the IRQ registers are available for
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE 0xF6000000
+#define S3C_ADDR_BASE CONFIG_S3C_ADDR_BASE
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
@@ -35,8 +35,14 @@
#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_HSOTG S3C_ADDR(0x00E00000) /* OTG */
+#define S3C_VA_HSPHY S3C_ADDR(0x00F00000) /* OTG PHY */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
+#define S3C_VA_KLOG_BUF S3C_ADDR(0x01100000) /* non-cached log buf */
+#define S3C_VA_SLOG_BUF S3C_ADDR(0x01400000) /* non-cached sched log buf */
+#define S3C_VA_AUXLOG_BUF S3C_ADDR(0x01600000) /* auxiliary log buf */
+
/* This is used for the CPU specific mappings that may be needed, so that
* they do not need to directly used S3C_ADDR() and thus make it easier to
* modify the space for mapping.
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/pd.h smdk4210/arch/arm/plat-samsung/include/plat/pd.h
index abb4bc3..832a403 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/pd.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/pd.h
@@ -11,20 +11,41 @@
#ifndef __ASM_PLAT_SAMSUNG_PD_H
#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
-struct samsung_pd_info {
- int (*enable)(struct device *dev);
- int (*disable)(struct device *dev);
- void __iomem *base;
-};
-
-enum exynos4_pd_block {
+enum exynos_pd_block {
PD_MFC,
PD_G3D,
PD_LCD0,
PD_LCD1,
PD_TV,
PD_CAM,
- PD_GPS
+ PD_GPS,
+ PD_GPS_ALIVE,
+ PD_ISP,
+ PD_MAUDIO,
+ PD_GSCL,
+ PD_DISP1,
+ PD_TOP,
+};
+
+struct samsung_pd_info {
+ int (*init)(struct device *dev);
+ int (*enable)(struct device *dev);
+ int (*disable)(struct device *dev);
+ int (*save)(struct device *dev);
+ int (*restore)(struct device *dev);
+ void __iomem *base;
+ void *data;
+ enum exynos_pd_block id;
+};
+
+struct exynos_pd_data {
+ void __iomem *clk_base;
+ void __iomem *clksrc_base;
+ void __iomem *read_base;
+ unsigned long read_phy_addr;
};
+int exynos_pd_init(struct device *dev);
+int exynos_pd_enable(struct device *dev);
+int exynos_pd_disable(struct device *dev);
#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/pm.h smdk4210/arch/arm/plat-samsung/include/plat/pm.h
index 7fb6f6b..5a8aa39 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/pm.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/pm.h
@@ -43,6 +43,10 @@ extern unsigned long s3c_irqwake_eintallow;
extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);
+extern void (*pm_cpu_restore)(void);
+extern int (*pm_prepare)(void);
+extern void (*pm_finish)(void);
+extern unsigned int (*pm_check_eint_pend)(void);
/* Flags for PM Control */
@@ -102,10 +106,12 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
#ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
extern int s3c24xx_irq_suspend(void);
extern void s3c24xx_irq_resume(void);
#else
+#define s3c_irq_wake NULL
#define s3c_irqext_wake NULL
#define s3c24xx_irq_suspend NULL
#define s3c24xx_irq_resume NULL
@@ -128,7 +134,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
@@ -151,10 +157,10 @@ extern void s3c_pm_check_restore(void);
extern void s3c_pm_check_cleanup(void);
extern void s3c_pm_check_store(void);
#else
-#define s3c_pm_check_prepare() do { } while(0)
-#define s3c_pm_check_restore() do { } while(0)
-#define s3c_pm_check_cleanup() do { } while(0)
-#define s3c_pm_check_store() do { } while(0)
+#define s3c_pm_check_prepare() do { } while (0)
+#define s3c_pm_check_restore() do { } while (0)
+#define s3c_pm_check_cleanup() do { } while (0)
+#define s3c_pm_check_store() do { } while (0)
#endif
/**
@@ -183,3 +189,5 @@ extern void s3c_pm_save_gpios(void);
extern void s3c_pm_save_core(void);
extern void s3c_pm_restore_core(void);
+
+extern unsigned long s3c_suspend_wakeup_stat;
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-adc.h smdk4210/arch/arm/plat-samsung/include/plat/regs-adc.h
index 7554c4f..b0759b1 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-adc.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -21,16 +21,19 @@
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S5P_ADCMUX S3C2410_ADCREG(0x1C)
#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
/* ADCCON Register Bits */
+#define S3C64XX_ADCCON_TSSEL (1<<17)
#define S3C64XX_ADCCON_RESSEL (1<<16)
#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 S5PV210_ADCCON_SELMUX(x) (((x)&0xF)<<0)
#define S3C2410_ADCCON_MUXMASK (0x7<<3)
#define S3C2410_ADCCON_STDBM (1<<2)
#define S3C2410_ADCCON_READ_START (1<<1)
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-fb-v4.h smdk4210/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
index 4c3647f..9c5534e 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -30,9 +30,17 @@
#define VIDCON1_FSTATUS_EVEN (1 << 15)
/* Video timing controls */
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDTCON0 (0x20010)
+#define VIDTCON1 (0x20014)
+#define VIDTCON2 (0x20018)
+#define VIDTCON3 (0x2001C)
+#else
#define VIDTCON0 (0x10)
#define VIDTCON1 (0x14)
#define VIDTCON2 (0x18)
+#define VIDTCON3 (0x1C)
+#endif
/* Window position controls */
@@ -43,9 +51,12 @@
#define VIDOSD_BASE (0x40)
#define VIDINTCON0 (0x130)
+#define VIDINTCON1 (0x134)
/* WINCONx */
+#define WINCONx_CSC_CON_EQ709 (1 << 28)
+#define WINCONx_CSC_CON_EQ601 (0 << 28)
#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
#define WINCONx_CSCWIDTH_SHIFT (26)
#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-fb.h smdk4210/arch/arm/plat-samsung/include/plat/regs-fb.h
index 8f39aa5..f6c450b 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -32,12 +32,27 @@
#define VIDCON0 (0x00)
#define VIDCON0_INTERLACE (1 << 29)
-#define VIDCON0_VIDOUT_MASK (0x3 << 26)
+
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON_VIDOUT_UP_MASK (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_UP_SHIFT (16)
+#define VIDOUT_CON_VIDOUT_UP_ALWAYS (0x0 << 16)
+#define VIDOUT_CON_VIDOUT_UP_START_FRAME (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_F_MASK (0x7 << 8)
+#define VIDOUT_CON_VIDOUT_F_SHIFT (8)
+#define VIDOUT_CON_VIDOUT_F_RGB (0x0 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI0 (0x2 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI1 (0x3 << 8)
+#define VIDOUT_CON_VIDOUT_F_WB (0x4 << 8)
+#endif
+
+#define VIDCON0_VIDOUT_MASK (0x7 << 26)
#define VIDCON0_VIDOUT_SHIFT (26)
#define VIDCON0_VIDOUT_RGB (0x0 << 26)
#define VIDCON0_VIDOUT_TV (0x1 << 26)
#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
+#define VIDCON0_VIDOUT_WB (0x4 << 26)
#define VIDCON0_L1_DATA_MASK (0x7 << 23)
#define VIDCON0_L1_DATA_SHIFT (23)
@@ -81,7 +96,17 @@
#define VIDCON0_ENVID (1 << 1)
#define VIDCON0_ENVID_F (1 << 0)
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON (0x20000)
+#define VIDCON1 (0x20004)
+#define REG_TIME2INIT (0x01b4)
+#define REG_TIME2SNP (0x01b8)
+#define DP_MIE_CLKCON (0x027c)
+#define FREERUNCON (0x005c)
+#else
#define VIDCON1 (0x04)
+#endif
+
#define VIDCON1_LINECNT_MASK (0x7ff << 16)
#define VIDCON1_LINECNT_SHIFT (16)
#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
@@ -90,7 +115,11 @@
#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
-#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH (0x3 << 13)
+#define VIDCON1_VSTATUS_MASK (0x3 << 13)
+#define VIDCON1_VCLK_MASK (0x3 << 9)
+#define VIDCON1_VCLK_HOLD (0x0 << 9)
+#define VIDCON1_VCLK_RUN (0x1 << 9)
#define VIDCON1_INV_VCLK (1 << 7)
#define VIDCON1_INV_HSYNC (1 << 6)
@@ -99,18 +128,27 @@
/* VIDCON2 */
-#define VIDCON2 (0x08)
-#define VIDCON2_EN601 (1 << 23)
-#define VIDCON2_TVFMTSEL_SW (1 << 14)
-
-#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
-#define VIDCON2_TVFMTSEL1_SHIFT (12)
-#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
-#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
-#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
-
-#define VIDCON2_ORGYCbCr (1 << 8)
-#define VIDCON2_YUVORDCrCb (1 << 7)
+#define VIDCON2 (0x08)
+#define VIDCON2_WB_SKIP_1_2 (1 << 0)
+#define VIDCON2_WB_SKIP_1_3 (1 << 1)
+#define VIDCON2_WB_SKIP_1_4 (3 << 0)
+#define VIDCON2_WB_SKIP_1_5 (1 << 2)
+#define VIDCON2_WB_SKIP_MASK (0x1f << 0)
+#define VIDCON2_EN601 (1 << 23)
+#define VIDCON2_WB_DISABLE (0 << 15)
+#define VIDCON2_WB_ENABLE (1 << 15)
+#define VIDCON2_WB_MASK (1 << 15)
+#define VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define VIDCON2_TVFORMATSEL_HW_SW_MASK (1 << 14)
+#define VIDCON2_TVFORMATSEL_MASK (0x3 << 12)
+#define VIDCON2_TVFORMATSEL_SHIFT (12)
+#define VIDCON2_TVFORMATSEL_RGB (0x0 << 12)
+#define VIDCON2_TVFORMATSEL_YUV422 (0x1 << 12)
+#define VIDCON2_TVFORMATSEL_YUV444 (0x2 << 12)
+
+#define VIDCON2_ORGYCbCr (1 << 8)
+#define VIDCON2_YUVORDCrCb (1 << 7)
/* PRTCON (S3C6410, S5PC100)
* Might not be present in the S3C6410 documentation,
@@ -163,24 +201,29 @@
#define VIDTCON1_HSPW_LIMIT (0xff)
#define VIDTCON1_HSPW(_x) ((_x) << 0)
-#define VIDTCON2 (0x18)
+/* VIDTCON2 */
+
+#define VIDTCON2_LINEVAL_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
#define VIDTCON2_LINEVAL_SHIFT (11)
#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
-#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
+#define VIDTCON2_LINEVAL(_x) (((_x) & 0x7ff) << 11)
+#define VIDTCON2_HOZVAL_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
#define VIDTCON2_HOZVAL_SHIFT (0)
#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
-#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
+#define VIDTCON2_HOZVAL(_x) (((_x) & 0x7ff) << 0)
/* WINCONx */
-
#define WINCONx_BITSWP (1 << 18)
#define WINCONx_BYTSWP (1 << 17)
#define WINCONx_HAWSWP (1 << 16)
#define WINCONx_WSWP (1 << 15)
+#define WINCONx_ENLOCAL_MASK (0xf << 15)
+#define WINCONx_INRGB_RGB (0 << 13)
+#define WINCONx_INRGB_YCBCR (1 << 13)
#define WINCONx_BURSTLEN_MASK (0x3 << 9)
#define WINCONx_BURSTLEN_SHIFT (9)
#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
@@ -200,6 +243,7 @@
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
#define WINCON1_BLD_PIX (1 << 6)
+#define WINCON1_BLD_PLANE (0 << 6)
#define WINCON1_ALPHA_SEL (1 << 1)
#define WINCON1_BPPMODE_MASK (0xf << 2)
@@ -228,25 +272,29 @@
/* Local input channels (windows 0-2) */
#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
+#define VIDOSDxA_TOPLEFT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
+#define VIDOSDxA_TOPLEFT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxA_TOPLEFT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
+#define VIDOSDxA_TOPLEFT_Y(_x) (((_x) & 0x7ff) << 0)
+#define VIDOSDxB_BOTRIGHT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
+#define VIDOSDxB_BOTRIGHT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxB_BOTRIGHT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
+#define VIDOSDxB_BOTRIGHT_Y(_x) (((_x) & 0x7ff) << 0)
/* For VIDOSD[1..4]C */
#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
@@ -278,15 +326,17 @@
#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
+#define VIDW_BUF_SIZE_OFFSET_E(_x) ((((_x) & 0x2000) >> 13) << 27)
#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
+#define VIDW_BUF_SIZE_OFFSET(_x) (((_x) & 0x1fff) << 13)
+#define VIDW_BUF_SIZE_PAGEWIDTH_E(_x) ((((_x) & 0x2000) >> 13) << 26)
#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x) (((_x) & 0x1fff) << 0)
/* Interrupt controls and status */
@@ -384,3 +434,22 @@
#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
+/* Clock gate mode control */
+#define REG_CLKGATE_MODE (0x1b0)
+#define REG_CLKGATE_MODE_AUTO_CLOCK_GATE (0 << 0)
+#define REG_CLKGATE_MODE_NON_CLOCK_GATE (1 << 0)
+
+/* Blending equation control */
+#define BLENDCON (0x260)
+#define BLENDCON_NEW_MASK (1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
+
+/* DP clock control */
+#define DPCLKCON (0x27c)
+#define DPCLKCON_ENABLE (1 << 1)
+
+/* Window alpha control */
+#define VIDW0ALPHA0 (0x200)
+#define VIDW0ALPHA1 (0x204)
+#define DUALRGB (0x27c)
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-serial.h smdk4210/arch/arm/plat-samsung/include/plat/regs-serial.h
index 116edfe..5adf78f 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -255,6 +255,8 @@ struct s3c24xx_uart_clksrc {
* arch/arm/mach-s3c2410/ directory.
*/
+struct uart_port;
+
struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
@@ -269,6 +271,9 @@ struct s3c2410_uartcfg {
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
+
+ void (*wake_peer)(struct uart_port *);
+ void (*set_runstate)(int onoff);
};
/* s3c24xx_uart_devs
@@ -282,4 +287,3 @@ extern struct platform_device *s3c24xx_uart_devs[4];
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h smdk4210/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
index 8107442..ee155ad 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -84,6 +84,23 @@ enum dma_ch {
DMACH_SLIMBUS4_TX,
DMACH_SLIMBUS5_RX,
DMACH_SLIMBUS5_TX,
+ DMACH_MIPI_HSI0,
+ DMACH_MIPI_HSI1,
+ DMACH_MIPI_HSI2,
+ DMACH_MIPI_HSI3,
+ DMACH_MIPI_HSI4,
+ DMACH_MIPI_HSI5,
+ DMACH_MIPI_HSI6,
+ DMACH_MIPI_HSI7,
+ DMACH_DISP1,
+ 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,
};
@@ -93,6 +110,11 @@ static inline bool s3c_dma_has_circular(void)
return true;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return true;
+}
+
#include <plat/dma.h>
#endif /* __S3C_DMA_PL330_H_ */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h smdk4210/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index 4c16fa3..353ceb6 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -71,5 +71,6 @@ extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+extern void exynos_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
#endif /* __S3C64XX_PLAT_SPI_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/sdhci.h smdk4210/arch/arm/plat-samsung/include/plat/sdhci.h
index 058e096..c0e3799 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/sdhci.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -18,6 +18,8 @@
#ifndef __PLAT_S3C_SDHCI_H
#define __PLAT_S3C_SDHCI_H __FILE__
+/* ignore mmc suspend/resume for BCM WIFI */
+#define S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME (1 << 30)
struct platform_device;
struct mmc_host;
struct mmc_card;
@@ -72,8 +74,11 @@ struct s3c_sdhci_platdata {
char **clocks; /* set of clock sources */
+ char *vmmc_name; /* name for regulator */
int ext_cd_gpio;
bool ext_cd_gpio_invert;
+ unsigned int pm_flags;
+
int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
int state));
int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
@@ -84,6 +89,10 @@ struct s3c_sdhci_platdata {
void __iomem *regbase,
struct mmc_ios *ios,
struct mmc_card *card);
+#ifdef CONFIG_MACH_PX
+ int (*ext_pdev)(struct platform_device *dev_id);
+#endif
+
};
/**
@@ -126,6 +135,10 @@ extern void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C2416 SDHCI setup */
@@ -390,4 +403,58 @@ static inline void exynos4_default_sdhci3(void) { }
#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+extern void mmc_force_presence_change(struct platform_device *pdev);
+
+/* EXYNOS5 SDHCI setup */
+#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
+extern char *exynos4_hsmmc_clksrcs[4];
+
+extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void exynos5_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = exynos5_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = exynos5_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = exynos5_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = exynos5_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void exynos5_default_sdhci0(void) { }
+static inline void exynos5_default_sdhci1(void) { }
+static inline void exynos5_default_sdhci2(void) { }
+static inline void exynos5_default_sdhci3(void) { }
+
+#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
#endif /* __PLAT_S3C_SDHCI_H */
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/ts.h smdk4210/arch/arm/plat-samsung/include/plat/ts.h
index 26fdb22..3fb52b9 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/ts.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/ts.h
@@ -14,10 +14,16 @@ struct s3c2410_ts_mach_info {
int delay;
int presc;
int oversampling_shift;
+
+ int cal_x_max;
+ int cal_y_max;
+ int cal_param[7];
+
void (*cfg_gpio)(struct platform_device *dev);
};
extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+extern void s3c24xx_ts1_set_platdata(struct s3c2410_ts_mach_info *);
/* defined by architecture to configure gpio */
extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/udc-hs.h smdk4210/arch/arm/plat-samsung/include/plat/udc-hs.h
index a22a4f2..9b90b08 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -27,3 +27,14 @@ struct s3c_hsotg_plat {
enum s3c_hsotg_dmamode dma;
unsigned int is_osc : 1;
};
+
+typedef enum usb_cable_status {
+ USB_CABLE_DETACHED = 0,
+ USB_CABLE_ATTACHED,
+ USB_OTGHOST_DETACHED,
+ USB_OTGHOST_ATTACHED,
+ USB_POWERED_HOST_DETACHED,
+ USB_POWERED_HOST_ATTACHED,
+ USB_CABLE_DETACHED_WITHOUT_NOTI,
+} usb_cable_status;
+
diff --git aosp-v3.0/arch/arm/plat-samsung/include/plat/watchdog-reset.h smdk4210/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..4dc5adf 100644
--- aosp-v3.0/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ smdk4210/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -10,26 +10,24 @@
* published by the Free Software Foundation.
*/
+#include <plat/clock.h>
#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__);
+ if (s3c2410_wdtclk)
+ clk_enable(s3c2410_wdtclk);
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
diff --git aosp-v3.0/arch/arm/plat-samsung/irq-uart.c smdk4210/arch/arm/plat-samsung/irq-uart.c
index 657405c..384f131 100644
--- aosp-v3.0/arch/arm/plat-samsung/irq-uart.c
+++ smdk4210/arch/arm/plat-samsung/irq-uart.c
@@ -23,6 +23,7 @@
#include <plat/irq-uart.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
+#include <asm/mach/irq.h>
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
@@ -32,6 +33,12 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
+
+ if (!(pend & 0xf))
+ do_bad_IRQ(irq, desc);
if (pend & (1 << 0))
generic_handle_irq(base);
@@ -41,6 +48,8 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(base + 2);
if (pend & (1 << 3))
generic_handle_irq(base + 3);
+
+ chained_irq_exit(chip, desc);
}
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
@@ -65,6 +74,8 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_mask_ack = irq_gc_mask_and_ack_set;
+ ct->chip.irq_disable = irq_gc_mask_and_ack_set;
ct->regs.ack = S3C64XX_UINTP;
ct->regs.mask = S3C64XX_UINTM;
irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
diff --git aosp-v3.0/arch/arm/plat-samsung/irq-vic-timer.c smdk4210/arch/arm/plat-samsung/irq-vic-timer.c
index f714d06..7837f48 100644
--- aosp-v3.0/arch/arm/plat-samsung/irq-vic-timer.c
+++ smdk4210/arch/arm/plat-samsung/irq-vic-timer.c
@@ -21,10 +21,15 @@
#include <mach/map.h>
#include <plat/irq-vic-timer.h>
#include <plat/regs-timer.h>
+#include <asm/mach/irq.h>
static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
generic_handle_irq((int)desc->irq_data.handler_data);
+ chained_irq_exit(chip, desc);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
diff --git aosp-v3.0/arch/arm/plat-samsung/pd.c smdk4210/arch/arm/plat-samsung/pd.c
index efe1d56..2d40889 100644
--- aosp-v3.0/arch/arm/plat-samsung/pd.c
+++ smdk4210/arch/arm/plat-samsung/pd.c
@@ -22,12 +22,22 @@ static int samsung_pd_probe(struct platform_device *pdev)
{
struct samsung_pd_info *pdata = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
+ int ret = 0;
if (!pdata) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
+ pdata->id = pdev->id;
+ if (pdata->init) {
+ ret = pdata->init(dev);
+ if (ret) {
+ dev_err(dev, "init fails");
+ return ret;
+ }
+ }
+
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -43,6 +53,32 @@ static int __devexit samsung_pd_remove(struct platform_device *pdev)
return 0;
}
+static int samsung_pd_suspend(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->save)
+ ret = pdata->save(dev);
+
+ dev_dbg(dev, "suspended\n");
+
+ return ret;
+}
+
+static int samsung_pd_resume(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->restore)
+ ret = pdata->restore(dev);
+
+ dev_dbg(dev, "resumed\n");
+
+ return ret;
+}
+
static int samsung_pd_runtime_suspend(struct device *dev)
{
struct samsung_pd_info *pdata = dev->platform_data;
@@ -51,7 +87,7 @@ static int samsung_pd_runtime_suspend(struct device *dev)
if (pdata->disable)
ret = pdata->disable(dev);
- dev_dbg(dev, "suspended\n");
+ dev_dbg(dev, "runtime suspended\n");
return ret;
}
@@ -63,11 +99,13 @@ static int samsung_pd_runtime_resume(struct device *dev)
if (pdata->enable)
ret = pdata->enable(dev);
- dev_dbg(dev, "resumed\n");
+ dev_dbg(dev, "runtime resumed\n");
return ret;
}
static const struct dev_pm_ops samsung_pd_pm_ops = {
+ .suspend = samsung_pd_suspend,
+ .resume = samsung_pd_resume,
.runtime_suspend = samsung_pd_runtime_suspend,
.runtime_resume = samsung_pd_runtime_resume,
};
diff --git aosp-v3.0/arch/arm/plat-samsung/pm-gpio.c smdk4210/arch/arm/plat-samsung/pm-gpio.c
index 9652820..c365b40 100644
--- aosp-v3.0/arch/arm/plat-samsung/pm-gpio.c
+++ smdk4210/arch/arm/plat-samsung/pm-gpio.c
@@ -21,6 +21,7 @@
#include <plat/gpio-core.h>
#include <plat/pm.h>
+#include <plat/cpu.h>
/* PM GPIO helpers */
@@ -318,6 +319,26 @@ static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
pm->save(ourchip);
}
+static int s3c_get_gpio_max_nr (void)
+{
+ static int gpio_max_nr = 0;
+
+ if (unlikely(!gpio_max_nr)) {
+ if (soc_is_exynos4210())
+ gpio_max_nr = EXYNOS4210_GPIO_END;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ gpio_max_nr = EXYNOS4212_GPIO_END;
+ else if (soc_is_exynos5210())
+ gpio_max_nr = EXYNOS5210_GPIO_END;
+ else if (soc_is_exynos5250())
+ gpio_max_nr = EXYNOS5250_GPIO_END;
+ else
+ gpio_max_nr = S3C_GPIO_END;
+ }
+
+ return gpio_max_nr;
+}
+
/**
* s3c_pm_save_gpios() - Save the state of the GPIO banks.
*
@@ -328,9 +349,12 @@ void s3c_pm_save_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
- ourchip = s3c_gpiolib_getchip(gpio_nr);
+ gpio_max_nr = s3c_get_gpio_max_nr();
+
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
continue;
@@ -368,8 +392,11 @@ void s3c_pm_restore_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
+
+ gpio_max_nr = s3c_get_gpio_max_nr();
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
diff --git aosp-v3.0/arch/arm/plat-samsung/pm.c smdk4210/arch/arm/plat-samsung/pm.c
index 5c0a440..5f304a7 100644
--- aosp-v3.0/arch/arm/plat-samsung/pm.c
+++ smdk4210/arch/arm/plat-samsung/pm.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/serial_core.h>
#include <linux/io.h>
+#include <linux/power/charger-manager.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h>
@@ -32,6 +33,7 @@
#include <mach/pm-core.h>
/* for external use */
+unsigned long s3c_suspend_wakeup_stat;
unsigned long s3c_pm_flags;
@@ -53,7 +55,9 @@ void s3c_pm_dbg(const char *fmt, ...)
vsprintf(buff, fmt, va);
va_end(va);
+#ifdef CONFIG_DEBUG_LL
printascii(buff);
+#endif
}
static inline void s3c_pm_debug_init(void)
@@ -63,7 +67,7 @@ static inline void s3c_pm_debug_init(void)
}
#else
-#define s3c_pm_debug_init() do { } while(0)
+#define s3c_pm_debug_init() do { } while (0)
#endif /* CONFIG_SAMSUNG_PM_DEBUG */
@@ -186,8 +190,13 @@ 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",
+#if defined(CONFIG_CPU_EXYNOS4210)
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#else
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
}
@@ -206,8 +215,13 @@ void s3c_pm_do_restore(struct sleep_save *ptr, int count)
void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
{
- for (; count > 0; count--, ptr++)
+ for (; count > 0; count--, ptr++) {
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("restore_core %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
+ }
}
/* s3c2410_pm_show_resume_irqs
@@ -223,15 +237,17 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start,
which &= ~mask;
for (i = 0; i <= 31; i++) {
- if (which & (1L<<i)) {
+ if (which & (1L<<i))
S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
- }
}
}
-
void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);
+void (*pm_cpu_restore)(void);
+int (*pm_prepare)(void);
+void (*pm_finish)(void);
+unsigned int (*pm_check_eint_pend)(void);
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
@@ -239,7 +255,9 @@ void (*pm_cpu_sleep)(void);
*
* central control for sleep/resume process
*/
-
+#ifdef CONFIG_FAST_BOOT
+extern bool fake_shut_down;
+#endif
static int s3c_pm_enter(suspend_state_t state)
{
/* ensure the debug is initialised (if enabled) */
@@ -265,9 +283,19 @@ static int s3c_pm_enter(suspend_state_t state)
return -EINVAL;
}
+ if (pm_check_eint_pend) {
+ u32 pending_eint = pm_check_eint_pend();
+ if (pending_eint) {
+ pr_warn("%s: Aborting sleep, EINT PENDING(0x%08x)\n",
+ __func__, pending_eint);
+ return -EBUSY;
+ }
+ }
+
/* save all necessary core registers not covered by the drivers */
s3c_pm_save_gpios();
+ s3c_pm_saved_gpios();
s3c_pm_save_uarts();
s3c_pm_save_core();
@@ -290,28 +318,57 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_check_store();
+#ifdef CONFIG_FAST_BOOT
+ if (fake_shut_down) {
+#if defined(CONFIG_SEC_MODEM) || defined(CONFIG_QC_MODEM)
+ /* Masking external wake up source
+ * only enable power key, FUEL ALERT, AP/IF PMIC IRQ
+ * and SIM Detect Irq
+ */
+ __raw_writel(0xdf77df7f, S5P_EINT_WAKEUP_MASK);
+#else
+ /* Masking external wake up source
+ * only enable power key, FUEL ALERT, AP/IF PMIC IRQ */
+ __raw_writel(0xff77df7f, S5P_EINT_WAKEUP_MASK);
+#endif
+ /* disable all system int */
+ __raw_writel(0xffffffff, S5P_WAKEUP_MASK);
+ }
+#endif
+
/* send the cpu to sleep... */
s3c_pm_arch_stop_clocks();
+ printk(KERN_ALERT "PM: SLEEP\n");
+
/* s3c_cpu_save will also act as our return point from when
* we resume as it saves its own register state and restores it
* during the resume. */
+ printk(KERN_ALERT "ARM_COREx_STATUS CORE1[0x%08x], CORE2[0x%08x], CORE3[0x%08x]\n",
+ __raw_readl(S5P_VA_PMU + 0x2084),
+ __raw_readl(S5P_VA_PMU + 0x2104),
+ __raw_readl(S5P_VA_PMU + 0x2184));
+
s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
/* restore the cpu state using the kernel's cpu init code. */
cpu_init();
- /* restore the system state */
-
s3c_pm_restore_core();
s3c_pm_restore_uarts();
s3c_pm_restore_gpios();
+ s3c_pm_restored_gpios();
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();
@@ -332,21 +389,54 @@ static int s3c_pm_enter(suspend_state_t state)
static int s3c_pm_prepare(void)
{
/* prepare check area if configured */
-
+#if defined(CONFIG_MACH_P8LTE) \
+ || defined(CONFIG_MACH_U1_NA_SPR) \
+ || defined(CONFIG_MACH_U1_NA_USCC)
+ disable_hlt();
+#endif
s3c_pm_check_prepare();
+
+ if (pm_prepare)
+ pm_prepare();
+
return 0;
}
static void s3c_pm_finish(void)
{
+ if (pm_finish)
+ pm_finish();
+
s3c_pm_check_cleanup();
+#if defined(CONFIG_MACH_P8LTE) \
+ || defined(CONFIG_MACH_U1_NA_SPR) \
+ || defined(CONFIG_MACH_U1_NA_USCC)
+ enable_hlt();
+#endif
+}
+
+#if defined(CONFIG_CHARGER_MANAGER)
+static bool s3c_cm_suspend_again(void)
+{
+ bool ret;
+
+ if (!is_charger_manager_active())
+ return false;
+
+ ret = cm_suspend_again();
+
+ return ret;
}
+#endif
static const struct platform_suspend_ops s3c_pm_ops = {
.enter = s3c_pm_enter,
.prepare = s3c_pm_prepare,
.finish = s3c_pm_finish,
.valid = suspend_valid_only_mem,
+#if defined(CONFIG_CHARGER_MANAGER)
+ .suspend_again = s3c_cm_suspend_again,
+#endif
};
/* s3c_pm_init
@@ -358,7 +448,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");
+ printk(KERN_INFO "S3C Power Management, Copyright 2004 Simtec Electronics\n");
suspend_set_ops(&s3c_pm_ops);
return 0;
diff --git aosp-v3.0/arch/arm/plat-samsung/pwm.c smdk4210/arch/arm/plat-samsung/pwm.c
index f37457c..bdc892a 100644
--- aosp-v3.0/arch/arm/plat-samsung/pwm.c
+++ smdk4210/arch/arm/plat-samsung/pwm.c
@@ -19,10 +19,12 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>
+#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/regs-timer.h>
+#include <plat/gpio-cfg.h>
struct pwm_device {
struct list_head list;
@@ -39,11 +41,28 @@ struct pwm_device {
unsigned char running;
unsigned char use_count;
unsigned char pwm_id;
+
+ unsigned long tcfg0;
+};
+
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ unsigned int gpio_no;
+ const char *gpio_name;
+ unsigned int gpio_set_value;
};
+struct s3c_pwm_pdata *to_pwm_pdata(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s3c_pwm_pdata *)pdev->dev.platform_data;
+}
+
#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 +127,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);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ pwm->running = 1;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
- pwm->running = 1;
return 0;
}
@@ -127,15 +152,19 @@ 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 +214,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,12 +259,13 @@ 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));
tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
tcon |= pwm_tcon_manulupdate(pwm);
tcon |= pwm_tcon_autoreload(pwm);
__raw_writel(tcon, S3C2410_TCON);
@@ -240,7 +273,10 @@ 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;
}
@@ -263,11 +299,21 @@ static int s3c_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pwm_device *pwm;
- unsigned long flags;
- unsigned long tcon;
+ struct s3c_pwm_pdata *pdata = to_pwm_pdata(dev);
unsigned int id = pdev->id;
int ret;
+ if (gpio_is_valid(pdata->gpio_no)) {
+ ret = gpio_request(pdata->gpio_no, pdata->gpio_name);
+ if (ret)
+ printk(KERN_ERR "failed to get GPIO for PWM0\n");
+ s3c_gpio_cfgpin(pdata->gpio_no, pdata->gpio_set_value);
+
+ /* Inserting the following for commit 2010.02.26: [BACKLIGHT] Fix PWM
+ driver handling GPIO routine (request but not free)*/
+ gpio_free(pdata->gpio_no);
+ }
+
if (id == 4) {
dev_err(dev, "TIMER4 is currently not supported\n");
return -ENXIO;
@@ -299,15 +345,6 @@ static int s3c_pwm_probe(struct platform_device *pdev)
goto err_clk_tin;
}
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
-
ret = pwm_register(pwm);
if (ret) {
dev_err(dev, "failed to register pwm\n");
@@ -359,18 +396,24 @@ static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
pwm->period_ns = 0;
pwm->duty_ns = 0;
+ clk_enable(pwm->clk);
+
+ pwm->tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
+
return 0;
}
static int s3c_pwm_resume(struct platform_device *pdev)
{
struct pwm_device *pwm = platform_get_drvdata(pdev);
- unsigned long tcon;
- /* Restore invertion */
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ clk_enable(pwm->clk);
+
+ __raw_writel(pwm->tcfg0, S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
return 0;
}
diff --git aosp-v3.0/arch/arm/plat-samsung/s3c-pl330.c smdk4210/arch/arm/plat-samsung/s3c-pl330.c
index f85638c..92f30f7 100644
--- aosp-v3.0/arch/arm/plat-samsung/s3c-pl330.c
+++ smdk4210/arch/arm/plat-samsung/s3c-pl330.c
@@ -17,6 +17,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+#include <linux/pm_runtime.h>
+#endif
#include <asm/hardware/pl330.h>
@@ -498,9 +501,11 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
spin_lock_irqsave(&res_lock, flags);
- r->x = NULL;
+ if (!r->infiniteloop) {
+ r->x = NULL;
- s3c_pl330_submit(ch, r);
+ s3c_pl330_submit(ch, r);
+ }
spin_unlock_irqrestore(&res_lock, flags);
@@ -513,12 +518,20 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
res = S3C2410_RES_ERR;
/* If last request had some xfer */
- if (xl) {
- xfer = container_of(xl, struct s3c_pl330_xfer, px);
- _finish_off(xfer, res, 0);
+ if (!r->infiniteloop) {
+ if (xl) {
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ _finish_off(xfer, res, 0);
+ } else {
+ dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+ __func__, __LINE__);
+ }
} else {
- dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
- __func__, __LINE__);
+ /* Do callback */
+
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ if (ch->callback_fn)
+ ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
}
}
@@ -660,8 +673,8 @@ ctrl_exit:
}
EXPORT_SYMBOL(s3c2410_dma_ctrl);
-int s3c2410_dma_enqueue(enum dma_ch id, void *token,
- dma_addr_t addr, int size)
+int s3c2410_dma_enqueue_ring(enum dma_ch id, void *token,
+ dma_addr_t addr, int size, int numofblock)
{
struct s3c_pl330_chan *ch;
struct s3c_pl330_xfer *xfer;
@@ -669,7 +682,6 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
int idx, ret = 0;
spin_lock_irqsave(&res_lock, flags);
-
ch = id_to_chan(id);
/* Error if invalid or free channel */
@@ -709,11 +721,13 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
/* Try submitting on either request */
idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
- if (!ch->req[idx].x)
+ if (!ch->req[idx].x) {
+ ch->req[idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[idx]);
- else
+ } else {
+ ch->req[1 - idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[1 - idx]);
-
+ }
spin_unlock_irqrestore(&res_lock, flags);
if (ch->options & S3C2410_DMAF_AUTOSTART)
@@ -726,7 +740,7 @@ enq_exit:
return ret;
}
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
+EXPORT_SYMBOL(s3c2410_dma_enqueue_ring);
int s3c2410_dma_request(enum dma_ch id,
struct s3c2410_dma_client *client,
@@ -747,9 +761,24 @@ int s3c2410_dma_request(enum dma_ch id,
dmac = ch->dmac;
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* enable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_get_sync(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
+ clk_enable(dmac->clk);
+
ch->pl330_chan_id = pl330_request_channel(dmac->pi);
if (!ch->pl330_chan_id) {
chan_release(ch);
+ clk_disable(dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
ret = -EBUSY;
goto req_exit;
}
@@ -860,7 +889,14 @@ 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);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(ch->dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
chan_release(ch);
free_exit:
@@ -986,6 +1022,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;
@@ -1057,6 +1105,16 @@ static int pl330_probe(struct platform_device *pdev)
goto probe_err1;
}
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* to use the runtime PM helper functions */
+ pm_runtime_enable(&pdev->dev);
+ /* enable the power domain */
+ if (pm_runtime_get_sync(&pdev->dev)) {
+ dev_err(&pdev->dev, "failed to get runtime pm\n");
+ ret = -ENODEV;
+ goto probe_err1;
+ }
+#endif
request_mem_region(res->start, resource_size(res), pdev->name);
pl330_info->base = ioremap(res->start, resource_size(res));
@@ -1131,6 +1189,11 @@ 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);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+#endif
return 0;
probe_err8:
@@ -1147,6 +1210,11 @@ probe_err3:
iounmap(pl330_info->base);
probe_err2:
release_mem_region(res->start, resource_size(res));
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#endif
probe_err1:
kfree(pl330_info);
@@ -1156,7 +1224,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, *ch_tmp;
unsigned long flags;
int del, found;
@@ -1180,7 +1248,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, ch_tmp, &chan_list, node) {
/* Only channels that are handled by this DMAC */
if (iface_of_dmac(dmac, ch->id))
@@ -1205,15 +1273,20 @@ static int pl330_remove(struct platform_device *pdev)
}
/* Disable operation clock */
- clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */
list_del(&dmac->node);
kfree(dmac);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
spin_unlock_irqrestore(&res_lock, flags);
-
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#else
+ spin_unlock_irqrestore(&res_lock, flags);
+#endif
return 0;
}
diff --git aosp-v3.0/arch/arm/tools/mach-types smdk4210/arch/arm/tools/mach-types
index 3b3776d..746ff98 100644
--- aosp-v3.0/arch/arm/tools/mach-types
+++ smdk4210/arch/arm/tools/mach-types
@@ -480,7 +480,7 @@ eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
-smdkc210 MACH_SMDKC210 SMDKC210 2838
+smdk4210 MACH_SMDKC210 SMDKC210 2838
omap3_braillo MACH_OMAP3_BRAILLO OMAP3_BRAILLO 2839
spyplug MACH_SPYPLUG SPYPLUG 2840
ginger MACH_GINGER GINGER 2841
@@ -590,7 +590,7 @@ bury_bl7582 MACH_BURY_BL7582 BURY_BL7582 2946
bury_bps5270 MACH_BURY_BPS5270 BURY_BPS5270 2947
basi MACH_BASI BASI 2948
tn200 MACH_TN200 TN200 2949
-c2mmi MACH_C2MMI C2MMI 2950
+c2mmi MACH_M3MMI C2MMI 2950
meson_6236m MACH_MESON_6236M MESON_6236M 2951
meson_8626m MACH_MESON_8626M MESON_8626M 2952
tube MACH_TUBE TUBE 2953
@@ -1004,6 +1004,7 @@ xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378
nuri MACH_NURI NURI 3379
janus MACH_JANUS JANUS 3380
ddnas MACH_DDNAS DDNAS 3381
+u1hd MACH_U1HD U1HD 3381
tag MACH_TAG TAG 3382
tagw MACH_TAGW TAGW 3383
nitrogen_vm_imx51 MACH_NITROGEN_VM_IMX51 NITROGEN_VM_IMX51 3384
@@ -1113,3 +1114,12 @@ blissc MACH_BLISSC BLISSC 3491
thales_adc MACH_THALES_ADC THALES_ADC 3492
ubisys_p9d_evp MACH_UBISYS_P9D_EVP UBISYS_P9D_EVP 3493
atdgp318 MACH_ATDGP318 ATDGP318 3494
+smdk4212 MACH_SMDK4212 SMDK4212 3698
+smdk4412 MACH_SMDK4412 SMDK4412 3765
+slp_pq MACH_SLP_PQ SLP_PQ 3766
+slp_pq_lte MACH_SLP_PQ_LTE SLP_PQ_LTE 3767
+smdk5210 MACH_SMDK5210 SMDK5210 3774
+smdk5250 MACH_SMDK5250 SMDK5250 3825
+trats MACH_TRATS TRATS 3928
+redwood MACH_REDWOOD REDWOOD 3768
+t0_lte MACH_SLP_T0_LTE SLP_T0_LTE 3769
\ No newline at end of file
diff --git aosp-v3.0/arch/arm/vfp/vfpmodule.c smdk4210/arch/arm/vfp/vfpmodule.c
index 78829fa..c00eb89 100644
--- aosp-v3.0/arch/arm/vfp/vfpmodule.c
+++ smdk4210/arch/arm/vfp/vfpmodule.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/cpu.h>
+#include <linux/hardirq.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/signal.h>
@@ -395,8 +396,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
static void vfp_enable(void *unused)
{
- u32 access = get_copro_access();
+ u32 access;
+ BUG_ON(preemptible());
+ access = get_copro_access();
/*
* Enable full access to VFP (cp10 and cp11)
*/
@@ -541,7 +544,7 @@ static int __init vfp_init(void)
unsigned int cpu_arch = cpu_architecture();
if (cpu_arch >= CPU_ARCH_ARMv6)
- vfp_enable(NULL);
+ on_each_cpu(vfp_enable, NULL, 1);
/*
* First check that there is a VFP that we can use.
@@ -562,8 +565,6 @@ static int __init vfp_init(void)
} else {
hotcpu_notifier(vfp_hotplug, 0);
- smp_call_function(vfp_enable, NULL, 1);
-
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
@@ -594,7 +595,6 @@ static int __init vfp_init(void)
elf_hwcap |= HWCAP_VFPv3D16;
}
#endif
-#ifdef CONFIG_NEON
/*
* Check for the presence of the Advanced SIMD
* load/store instructions, integer and single
@@ -602,10 +602,13 @@ static int __init vfp_init(void)
* for NEON if the hardware has the MVFR registers.
*/
if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_NEON
if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
elf_hwcap |= HWCAP_NEON;
- }
#endif
+ if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+ elf_hwcap |= HWCAP_VFPv4;
+ }
}
return 0;
}
diff --git aosp-v3.0/block/Kconfig.iosched smdk4210/block/Kconfig.iosched
index 3199b76..ee5d210 100644
--- aosp-v3.0/block/Kconfig.iosched
+++ smdk4210/block/Kconfig.iosched
@@ -43,6 +43,16 @@ config CFQ_GROUP_IOSCHED
---help---
Enable group IO scheduling in CFQ.
+config IOSCHED_SIO
+ tristate "Simple I/O scheduler"
+ default y
+ ---help---
+ The Simple I/O scheduler is an extremely simple scheduler,
+ based on noop and deadline, that relies on deadlines to
+ ensure fairness. The algorithm does not do any sorting but
+ basic merging, trying to keep a minimum overhead. It is aimed
+ mainly for aleatory access devices (eg: flash devices).
+
choice
prompt "Default I/O scheduler"
default DEFAULT_CFQ
@@ -56,6 +66,9 @@ choice
config DEFAULT_CFQ
bool "CFQ" if IOSCHED_CFQ=y
+ config DEFAULT_SIO
+ bool "SIO" if IOSCHED_SIO=y
+
config DEFAULT_NOOP
bool "No-op"
@@ -65,6 +78,7 @@ config DEFAULT_IOSCHED
string
default "deadline" if DEFAULT_DEADLINE
default "cfq" if DEFAULT_CFQ
+ default "sio" if DEFAULT_SIO
default "noop" if DEFAULT_NOOP
endmenu
diff --git aosp-v3.0/block/Makefile smdk4210/block/Makefile
index 0fec4b3..529ae51 100644
--- aosp-v3.0/block/Makefile
+++ smdk4210/block/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
+obj-$(CONFIG_IOSCHED_SIO) += sio-iosched.o
obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
diff --git aosp-v3.0/block/blk-cgroup.c smdk4210/block/blk-cgroup.c
index b596e54..345843f 100644
--- aosp-v3.0/block/blk-cgroup.c
+++ smdk4210/block/blk-cgroup.c
@@ -1660,7 +1660,10 @@ static void __exit exit_cgroup_blkio(void)
{
cgroup_unload_subsys(&blkio_subsys);
}
-
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(init_cgroup_blkio);
+#else
module_init(init_cgroup_blkio);
+#endif
module_exit(exit_cgroup_blkio);
MODULE_LICENSE("GPL");
diff --git aosp-v3.0/block/blk-ioc.c smdk4210/block/blk-ioc.c
index 342eae9..9be30fe 100644
--- aosp-v3.0/block/blk-ioc.c
+++ smdk4210/block/blk-ioc.c
@@ -161,4 +161,8 @@ static int __init blk_ioc_init(void)
sizeof(struct io_context), 0, SLAB_PANIC, NULL);
return 0;
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(blk_ioc_init);
+#else
subsys_initcall(blk_ioc_init);
+#endif
diff --git aosp-v3.0/block/blk-settings.c smdk4210/block/blk-settings.c
index fa1eb04..dfd0270 100644
--- aosp-v3.0/block/blk-settings.c
+++ smdk4210/block/blk-settings.c
@@ -803,4 +803,8 @@ static int __init blk_settings_init(void)
blk_max_pfn = max_pfn - 1;
return 0;
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(blk_settings_init);
+#else
subsys_initcall(blk_settings_init);
+#endif
diff --git aosp-v3.0/block/cfq-iosched.c smdk4210/block/cfq-iosched.c
index 23500ac..bfe3bbe 100644
--- aosp-v3.0/block/cfq-iosched.c
+++ smdk4210/block/cfq-iosched.c
@@ -2060,6 +2060,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
cfq_remove_request(rq);
cfqq->dispatched++;
(RQ_CFQG(rq))->dispatched++;
+ rq->ioprio = IOPRIO_PRIO_VALUE(cfqq->ioprio_class, cfqq->ioprio);
elv_dispatch_sort(q, rq);
cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++;
@@ -4289,7 +4290,11 @@ static void __exit cfq_exit(void)
cfq_slab_kill();
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(cfq_init);
+#else
module_init(cfq_init);
+#endif
module_exit(cfq_exit);
MODULE_AUTHOR("Jens Axboe");
diff --git aosp-v3.0/block/deadline-iosched.c smdk4210/block/deadline-iosched.c
index 5139c0e..301a779 100644
--- aosp-v3.0/block/deadline-iosched.c
+++ smdk4210/block/deadline-iosched.c
@@ -460,7 +460,11 @@ static void __exit deadline_exit(void)
elv_unregister(&iosched_deadline);
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(deadline_init);
+#else
module_init(deadline_init);
+#endif
module_exit(deadline_exit);
MODULE_AUTHOR("Jens Axboe");
diff --git aosp-v3.0/block/genhd.c smdk4210/block/genhd.c
index 026d070..de7fc3e 100644
--- aosp-v3.0/block/genhd.c
+++ smdk4210/block/genhd.c
@@ -916,7 +916,11 @@ static int __init genhd_device_init(void)
return 0;
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(genhd_device_init);
+#else
subsys_initcall(genhd_device_init);
+#endif
static ssize_t disk_range_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -1129,6 +1133,10 @@ static int disk_uevent(struct device *dev, struct kobj_uevent_env *env)
cnt++;
disk_part_iter_exit(&piter);
add_uevent_var(env, "NPARTS=%u", cnt);
+#ifdef CONFIG_USB_HOST_NOTIFY
+ if (disk->interfaces == GENHD_IF_USB)
+ add_uevent_var(env, "MEDIAPRST=%d", disk->media_present);
+#endif
return 0;
}
@@ -1606,12 +1614,15 @@ static void disk_events_workfn(struct work_struct *work)
struct gendisk *disk = ev->disk;
char *envp[ARRAY_SIZE(disk_uevents) + 1] = { };
unsigned int clearing = ev->clearing;
- unsigned int events;
+ unsigned int events = 0;
unsigned long intv;
int nr_events = 0, i;
- /* check events */
- events = disk->fops->check_events(disk, clearing);
+#ifdef CONFIG_USB_HOST_NOTIFY
+ if (disk->interfaces != GENHD_IF_USB)
+ /* check events */
+ events = disk->fops->check_events(disk, clearing);
+#endif
/* accumulate pending events and schedule next poll if necessary */
spin_lock_irq(&ev->lock);
@@ -1635,8 +1646,13 @@ static void disk_events_workfn(struct work_struct *work)
if (events & disk->events & (1 << i))
envp[nr_events++] = disk_uevents[i];
- if (nr_events)
- kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_USB_HOST_NOTIFY
+ if (disk->interfaces != GENHD_IF_USB) {
+ if (nr_events)
+ kobject_uevent_env(&disk_to_dev(disk)->kobj,
+ KOBJ_CHANGE, envp);
+ }
+#endif
}
/*
diff --git aosp-v3.0/block/noop-iosched.c smdk4210/block/noop-iosched.c
index 06389e9..18f8bdd 100644
--- aosp-v3.0/block/noop-iosched.c
+++ smdk4210/block/noop-iosched.c
@@ -104,7 +104,11 @@ static void __exit noop_exit(void)
elv_unregister(&elevator_noop);
}
+#ifdef CONFIG_FAST_RESUME
+beforeresume_initcall(noop_init);
+#else
module_init(noop_init);
+#endif
module_exit(noop_exit);
diff --git aosp-v3.0/crypto/Kconfig smdk4210/crypto/Kconfig
index 87b22ca..3a6933c 100644
--- aosp-v3.0/crypto/Kconfig
+++ smdk4210/crypto/Kconfig
@@ -23,12 +23,22 @@ comment "Crypto core or helper"
config CRYPTO_FIPS
bool "FIPS 200 compliance"
- depends on CRYPTO_ANSI_CPRNG && !CRYPTO_MANAGER_DISABLE_TESTS
+ depends on CRYPTO_ANSI_CPRNG
help
This options enables the fips boot option which is
required if you want to system to operate in a FIPS 200
certification. You should say no unless you know what
- this is.
+ this is. Note that CRYPTO_ANSI_CPRNG is required if this
+ option is selected
+
+config CRYPTO_FIPS_INTEG_OFFSET
+ hex "FIPS integrity check zImage offset"
+ default 0x20000000
+ help
+ This options sets the offset from stext address where
+ zImage will be copied for integrity check if you want
+ to system to operate in FIPS mode, which enables
+ kernel crypto module.
config CRYPTO_ALGAPI
tristate
@@ -100,13 +110,13 @@ config CRYPTO_MANAGER2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
-config CRYPTO_MANAGER_DISABLE_TESTS
- bool "Disable run-time self tests"
+config CRYPTO_MANAGER_TESTS
+ bool "Run algolithms' self-tests"
default y
depends on CRYPTO_MANAGER2
help
- Disable run-time self tests that normally take place at
- algorithm registration.
+ Run cryptomanager's tests for the new crypto algorithms being
+ registered.
config CRYPTO_GF128MUL
tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
@@ -161,7 +171,6 @@ config CRYPTO_AUTHENC
config CRYPTO_TEST
tristate "Testing module"
- depends on m
select CRYPTO_MANAGER
help
Quick & dirty crypto test module.
diff --git aosp-v3.0/crypto/Makefile smdk4210/crypto/Makefile
index ce5a813..69c46ed 100644
--- aosp-v3.0/crypto/Makefile
+++ smdk4210/crypto/Makefile
@@ -2,6 +2,11 @@
# Cryptographic API
#
+ifeq ($(USE_SEC_FIPS_MODE),true)
+FIPS=fips_
+endif
+obj-$(CONFIG_CRYPTO_FIPS) += fips_integrity.o
+
obj-$(CONFIG_CRYPTO) += crypto.o
crypto-y := api.o cipher.o compress.o
diff --git aosp-v3.0/crypto/ablkcipher.c smdk4210/crypto/ablkcipher.c
index fdc67d3..f43b70a 100644
--- aosp-v3.0/crypto/ablkcipher.c
+++ smdk4210/crypto/ablkcipher.c
@@ -50,6 +50,11 @@ void __ablkcipher_walk_complete(struct ablkcipher_walk *walk)
{
struct ablkcipher_buffer *p, *tmp;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return;
+#endif
+
list_for_each_entry_safe(p, tmp, &walk->buffers, entry) {
ablkcipher_buffer_write(p);
list_del(&p->entry);
@@ -112,6 +117,11 @@ int ablkcipher_walk_done(struct ablkcipher_request *req,
struct crypto_tfm *tfm = req->base.tfm;
unsigned int nbytes = 0;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if (likely(err >= 0)) {
unsigned int n = walk->nbytes - err;
@@ -597,6 +607,11 @@ int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
struct crypto_alg *alg;
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
type = crypto_skcipher_type(type);
mask = crypto_skcipher_mask(mask);
diff --git aosp-v3.0/crypto/ahash.c smdk4210/crypto/ahash.c
index f669822..5f6a8e4 100644
--- aosp-v3.0/crypto/ahash.c
+++ smdk4210/crypto/ahash.c
@@ -78,6 +78,11 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
unsigned int alignmask = walk->alignmask;
unsigned int nbytes = walk->entrylen;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
walk->data -= walk->offset;
if (nbytes && walk->offset & alignmask && !err) {
@@ -115,6 +120,11 @@ EXPORT_SYMBOL_GPL(crypto_hash_walk_done);
int crypto_hash_walk_first(struct ahash_request *req,
struct crypto_hash_walk *walk)
{
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
walk->total = req->nbytes;
if (!walk->total)
@@ -132,6 +142,11 @@ int crypto_hash_walk_first_compat(struct hash_desc *hdesc,
struct crypto_hash_walk *walk,
struct scatterlist *sg, unsigned int len)
{
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
walk->total = len;
if (!walk->total)
@@ -250,6 +265,11 @@ static int crypto_ahash_op(struct ahash_request *req,
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
unsigned long alignmask = crypto_ahash_alignmask(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if ((unsigned long)req->result & alignmask)
return ahash_op_unaligned(req, op);
@@ -366,6 +386,11 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
struct crypto_ahash *hash = __crypto_ahash_cast(tfm);
struct ahash_alg *alg = crypto_ahash_alg(hash);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
hash->setkey = ahash_nosetkey;
hash->export = ahash_no_export;
hash->import = ahash_no_import;
@@ -468,6 +493,11 @@ int ahash_register_instance(struct crypto_template *tmpl,
{
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
err = ahash_prepare_alg(&inst->alg);
if (err)
return err;
diff --git aosp-v3.0/crypto/algapi.c smdk4210/crypto/algapi.c
index c3cf1a6..3fa383c 100644
--- aosp-v3.0/crypto/algapi.c
+++ smdk4210/crypto/algapi.c
@@ -61,6 +61,15 @@ static inline int crypto_set_driver_name(struct crypto_alg *alg)
static int crypto_check_alg(struct crypto_alg *alg)
{
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err())) {
+ printk(KERN_ERR
+ "crypto_check_alg failed due to FIPS error: %s",
+ alg->cra_name);
+ return -EACCES;
+ }
+#endif
+
if (alg->cra_alignmask & (alg->cra_alignmask + 1))
return -EINVAL;
@@ -355,6 +364,15 @@ int crypto_register_alg(struct crypto_alg *alg)
struct crypto_larval *larval;
int err;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err())) {
+ printk(KERN_ERR
+ "Unable to registrer alg: %s because of FIPS ERROR\n"
+ , alg->cra_name);
+ return -EACCES;
+ }
+#endif
+
err = crypto_check_alg(alg);
if (err)
return err;
@@ -411,6 +429,11 @@ int crypto_register_template(struct crypto_template *tmpl)
struct crypto_template *q;
int err = -EEXIST;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
down_write(&crypto_alg_sem);
list_for_each_entry(q, &crypto_template_list, list) {
@@ -478,6 +501,13 @@ static struct crypto_template *__crypto_lookup_template(const char *name)
struct crypto_template *crypto_lookup_template(const char *name)
{
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err())) {
+ printk(KERN_ERR
+ "crypto_lookup failed due to FIPS error: %s", name);
+ return -EACCES;
+ }
+#endif
return try_then_request_module(__crypto_lookup_template(name), name);
}
EXPORT_SYMBOL_GPL(crypto_lookup_template);
@@ -488,6 +518,11 @@ int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_larval *larval;
int err;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
err = crypto_check_alg(&inst->alg);
if (err)
goto err;
@@ -523,6 +558,11 @@ int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
{
int err = -EAGAIN;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
spawn->inst = inst;
spawn->mask = mask;
@@ -738,6 +778,11 @@ void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
char *p;
int err;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
GFP_KERNEL);
if (!p)
@@ -769,6 +814,11 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
struct crypto_spawn *spawn;
int err;
+ #ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
inst = crypto_alloc_instance2(name, alg, 0);
if (IS_ERR(inst))
goto out;
@@ -805,6 +855,11 @@ int crypto_enqueue_request(struct crypto_queue *queue,
{
int err = -EINPROGRESS;
+#ifdef CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
if (unlikely(queue->qlen >= queue->max_qlen)) {
err = -EBUSY;
if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
@@ -909,13 +964,13 @@ EXPORT_SYMBOL_GPL(crypto_xor);
static int __init crypto_algapi_init(void)
{
- crypto_init_proc();
+ /*crypto_init_proc(); //Moved to testmgr*/
return 0;
}
static void __exit crypto_algapi_exit(void)
{
- crypto_exit_proc();
+ /*crypto_exit_proc(); //Moved to testmgr*/
}
module_init(crypto_algapi_init);
diff --git aosp-v3.0/crypto/ansi_cprng.c smdk4210/crypto/ansi_cprng.c
index ffa0245..e8213b9 100644
--- aosp-v3.0/crypto/ansi_cprng.c
+++ smdk4210/crypto/ansi_cprng.c
@@ -126,6 +126,10 @@ static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
output = ctx->rand_data;
break;
case 2:
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EINVAL;
+#endif
/*
* First check that we didn't produce the same
* random data that we did last time around through this
@@ -133,8 +137,9 @@ static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
if (!memcmp(ctx->rand_data, ctx->last_rand_data,
DEFAULT_BLK_SZ)) {
if (cont_test) {
- panic("cprng %p Failed repetition check!\n",
- ctx);
+#ifdef CONFIG_CRYPTO_FIPS
+ set_in_fips_err();
+#endif
}
printk(KERN_ERR
@@ -372,6 +377,11 @@ static int cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ)
return -EINVAL;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (!memcmp(key, seed, DEFAULT_PRNG_KSZ))
+ return -EINVAL;
+#endif
+
if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ))
dt = key + DEFAULT_PRNG_KSZ;
@@ -408,6 +418,11 @@ static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
{
struct prng_context *prng = crypto_rng_ctx(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EINVAL;
+#endif
+
return get_prng_bytes(rdata, dlen, prng, 1);
}
diff --git aosp-v3.0/crypto/api.c smdk4210/crypto/api.c
index 033a714..0686dc5 100644
--- aosp-v3.0/crypto/api.c
+++ smdk4210/crypto/api.c
@@ -361,6 +361,11 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
unsigned int tfm_size;
int err = -ENOMEM;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask);
tfm = kzalloc(tfm_size, GFP_KERNEL);
if (tfm == NULL)
@@ -417,6 +422,11 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
struct crypto_tfm *tfm;
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
for (;;) {
struct crypto_alg *alg;
@@ -455,6 +465,13 @@ void *crypto_create_tfm(struct crypto_alg *alg,
unsigned int total;
int err = -ENOMEM;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err())) {
+ printk(KERN_ERR
+ "Fail crypto_create_tfm due to fips error state.\n");
+ return ERR_PTR(-EACCES);
+ }
+#endif
tfmsize = frontend->tfmsize;
total = tfmsize + sizeof(*tfm) + frontend->extsize(alg);
@@ -534,6 +551,11 @@ void *crypto_alloc_tfm(const char *alg_name,
void *tfm;
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
for (;;) {
struct crypto_alg *alg;
diff --git aosp-v3.0/crypto/internal.h smdk4210/crypto/internal.h
index d4384b0..0e7e9fd 100644
--- aosp-v3.0/crypto/internal.h
+++ smdk4210/crypto/internal.h
@@ -51,7 +51,14 @@ extern struct rw_semaphore crypto_alg_sem;
extern struct blocking_notifier_head crypto_chain;
#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_CRYPTO_FIPS
+void set_in_fips_err(void);
+void __init crypto_init_proc(int *fips_error);
+void do_integrity_check(void);
+int testmgr_crypto_proc_init(void);
+#else
void __init crypto_init_proc(void);
+#endif
void __exit crypto_exit_proc(void);
#else
static inline void crypto_init_proc(void)
@@ -138,4 +145,3 @@ static inline void crypto_notify(unsigned long val, void *v)
}
#endif /* _CRYPTO_INTERNAL_H */
-
diff --git aosp-v3.0/crypto/proc.c smdk4210/crypto/proc.c
index 58fef67..2c0b607 100644
--- aosp-v3.0/crypto/proc.c
+++ smdk4210/crypto/proc.c
@@ -25,8 +25,7 @@
#ifdef CONFIG_CRYPTO_FIPS
static struct ctl_table crypto_sysctl_table[] = {
{
- .procname = "fips_enabled",
- .data = &fips_enabled,
+ .procname = "fips_status",
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = proc_dointvec
@@ -141,11 +140,20 @@ static const struct file_operations proc_crypto_ops = {
.release = seq_release
};
+#ifdef CONFIG_CRYPTO_FIPS
+void __init crypto_init_proc(int *fips_error)
+{
+ proc_create("crypto", 0, NULL, &proc_crypto_ops);
+ crypto_sysctl_table[0].data = fips_error;
+ crypto_proc_fips_init();
+}
+#else
void __init crypto_init_proc(void)
{
proc_create("crypto", 0, NULL, &proc_crypto_ops);
crypto_proc_fips_init();
}
+#endif
void __exit crypto_exit_proc(void)
{
diff --git aosp-v3.0/crypto/shash.c smdk4210/crypto/shash.c
index 76f74b9..e44549c 100644
--- aosp-v3.0/crypto/shash.c
+++ smdk4210/crypto/shash.c
@@ -99,6 +99,11 @@ int crypto_shash_update(struct shash_desc *desc, const u8 *data,
struct shash_alg *shash = crypto_shash_alg(tfm);
unsigned long alignmask = crypto_shash_alignmask(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if ((unsigned long)data & alignmask)
return shash_update_unaligned(desc, data, len);
@@ -134,6 +139,11 @@ int crypto_shash_final(struct shash_desc *desc, u8 *out)
struct shash_alg *shash = crypto_shash_alg(tfm);
unsigned long alignmask = crypto_shash_alignmask(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if ((unsigned long)out & alignmask)
return shash_final_unaligned(desc, out);
@@ -155,6 +165,11 @@ int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
struct shash_alg *shash = crypto_shash_alg(tfm);
unsigned long alignmask = crypto_shash_alignmask(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if (((unsigned long)data | (unsigned long)out) & alignmask)
return shash_finup_unaligned(desc, data, len, out);
@@ -176,6 +191,11 @@ int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
struct shash_alg *shash = crypto_shash_alg(tfm);
unsigned long alignmask = crypto_shash_alignmask(tfm);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if (((unsigned long)data | (unsigned long)out) & alignmask)
return shash_digest_unaligned(desc, data, len, out);
@@ -208,6 +228,11 @@ static int shash_async_init(struct ahash_request *req)
struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
struct shash_desc *desc = ahash_request_ctx(req);
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
desc->tfm = *ctx;
desc->flags = req->base.flags;
@@ -219,6 +244,11 @@ int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc)
struct crypto_hash_walk walk;
int nbytes;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
nbytes = crypto_hash_walk_done(&walk, nbytes))
nbytes = crypto_shash_update(desc, walk.data, nbytes);
@@ -242,6 +272,11 @@ int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc)
struct crypto_hash_walk walk;
int nbytes;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
nbytes = crypto_hash_walk_first(req, &walk);
if (!nbytes)
return crypto_shash_final(desc, req->result);
@@ -276,6 +311,11 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
unsigned int nbytes = req->nbytes;
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
void *data;
@@ -334,6 +374,11 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
struct crypto_shash *shash;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
if (!crypto_mod_get(calg))
return -EAGAIN;
@@ -550,6 +595,11 @@ static const struct crypto_type crypto_shash_type = {
struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
u32 mask)
{
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return ERR_PTR(-EACCES);
+#endif
+
return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_alloc_shash);
@@ -587,6 +637,11 @@ int crypto_register_shash(struct shash_alg *alg)
struct crypto_alg *base = &alg->base;
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
err = shash_prepare_alg(alg);
if (err)
return err;
@@ -606,6 +661,11 @@ int shash_register_instance(struct crypto_template *tmpl,
{
int err;
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
err = shash_prepare_alg(&inst->alg);
if (err)
return err;
@@ -625,6 +685,11 @@ int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn,
struct shash_alg *alg,
struct crypto_instance *inst)
{
+#ifdef CONFIG_CRYPTO_FIPS
+ if (unlikely(in_fips_err()))
+ return -EACCES;
+#endif
+
return crypto_init_spawn2(&spawn->base, &alg->base, inst,
&crypto_shash_type);
}
diff --git aosp-v3.0/crypto/tcrypt.c smdk4210/crypto/tcrypt.c
index 2222617..093764e 100644
--- aosp-v3.0/crypto/tcrypt.c
+++ smdk4210/crypto/tcrypt.c
@@ -33,9 +33,12 @@
#include <linux/jiffies.h>
#include <linux/timex.h>
#include <linux/interrupt.h>
+#ifdef CRYPTO_SPEED_TESTS
#include "tcrypt.h"
+#endif
#include "internal.h"
+#ifdef CRYPTO_SPEED_TESTS
/*
* Need slab memory for testing (size in number of pages).
*/
@@ -51,12 +54,15 @@
* Used by test_cipher_speed()
*/
static unsigned int sec;
+#endif
static char *alg = NULL;
static u32 type;
static u32 mask;
static int mode;
+#ifdef CRYPTO_SPEED_TESTS
static char *tvmem[TVMEMSIZE];
+#endif
static char *check[] = {
"des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
@@ -66,7 +72,7 @@ static char *check[] = {
"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
"lzo", "cts", "zlib", NULL
};
-
+#ifdef CRYPTO_SPEED_TESTS
static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
struct scatterlist *sg, int blen, int sec)
{
@@ -718,6 +724,7 @@ static void test_ahash_speed(const char *algo, unsigned int sec,
out:
crypto_free_ahash(tfm);
}
+#endif
static void test_available(void)
{
@@ -752,15 +759,17 @@ static int do_test(int m)
for (i = 1; i < 200; i++)
ret += do_test(i);
break;
-
+#ifdef CONFIG_CRYPTO_MD5
case 1:
ret += tcrypt_test("md5");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SHA1
case 2:
ret += tcrypt_test("sha1");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_DES
case 3:
ret += tcrypt_test("ecb(des)");
ret += tcrypt_test("cbc(des)");
@@ -770,38 +779,47 @@ static int do_test(int m)
ret += tcrypt_test("ecb(des3_ede)");
ret += tcrypt_test("cbc(des3_ede)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_MD4
case 5:
ret += tcrypt_test("md4");
break;
-
+#endif
case 6:
ret += tcrypt_test("sha256");
break;
-
+#ifdef CONFIG_CRYPTO_BLOWFISH
case 7:
ret += tcrypt_test("ecb(blowfish)");
ret += tcrypt_test("cbc(blowfish)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_TWOFISH
case 8:
ret += tcrypt_test("ecb(twofish)");
ret += tcrypt_test("cbc(twofish)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SERPENT
case 9:
ret += tcrypt_test("ecb(serpent)");
break;
-
+#endif
case 10:
ret += tcrypt_test("ecb(aes)");
ret += tcrypt_test("cbc(aes)");
+#ifdef CONFIG_CRYPTO_LRW
ret += tcrypt_test("lrw(aes)");
+#endif
+#ifdef CONFIG_CRYPTO_XTS
ret += tcrypt_test("xts(aes)");
+#endif
+#ifdef CONFIG_CRYPTO_CTR
ret += tcrypt_test("ctr(aes)");
ret += tcrypt_test("rfc3686(ctr(aes))");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SHA512
case 11:
ret += tcrypt_test("sha384");
break;
@@ -809,31 +827,34 @@ static int do_test(int m)
case 12:
ret += tcrypt_test("sha512");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_DEFLATE
case 13:
ret += tcrypt_test("deflate");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CAST5
case 14:
ret += tcrypt_test("ecb(cast5)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CAST6
case 15:
ret += tcrypt_test("ecb(cast6)");
break;
-
+#endif
case 16:
ret += tcrypt_test("ecb(arc4)");
break;
-
+#ifdef CONFIG_CRYPTO_MICHAEL_MIC
case 17:
ret += tcrypt_test("michael_mic");
break;
-
+#endif
case 18:
ret += tcrypt_test("crc32c");
break;
-
+#ifdef CONFIG_CRYPTO_TEA
case 19:
ret += tcrypt_test("ecb(tea)");
break;
@@ -841,11 +862,13 @@ static int do_test(int m)
case 20:
ret += tcrypt_test("ecb(xtea)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_KHAZAD
case 21:
ret += tcrypt_test("ecb(khazad)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_WP512
case 22:
ret += tcrypt_test("wp512");
break;
@@ -857,16 +880,19 @@ static int do_test(int m)
case 24:
ret += tcrypt_test("wp256");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SERPENT
case 25:
ret += tcrypt_test("ecb(tnepres)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_ANUBIS
case 26:
ret += tcrypt_test("ecb(anubis)");
ret += tcrypt_test("cbc(anubis)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_TGR192
case 27:
ret += tcrypt_test("tgr192");
break;
@@ -879,83 +905,100 @@ static int do_test(int m)
case 29:
ret += tcrypt_test("tgr128");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_TEA
case 30:
ret += tcrypt_test("ecb(xeta)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_FCRYPT
case 31:
ret += tcrypt_test("pcbc(fcrypt)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CAMELLIA
case 32:
ret += tcrypt_test("ecb(camellia)");
ret += tcrypt_test("cbc(camellia)");
break;
+#endif
case 33:
ret += tcrypt_test("sha224");
break;
-
+#ifdef CONFIG_CRYPTO_SALSA20
case 34:
ret += tcrypt_test("salsa20");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_GCM
case 35:
ret += tcrypt_test("gcm(aes)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_LZO
case 36:
ret += tcrypt_test("lzo");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CCM
case 37:
ret += tcrypt_test("ccm(aes)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CTS
case 38:
ret += tcrypt_test("cts(cbc(aes))");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_RMD128
case 39:
ret += tcrypt_test("rmd128");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_RMD160
case 40:
ret += tcrypt_test("rmd160");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_RMD256
case 41:
ret += tcrypt_test("rmd256");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_RMD320
case 42:
ret += tcrypt_test("rmd320");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SEED
case 43:
ret += tcrypt_test("ecb(seed)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_ZLIB
case 44:
ret += tcrypt_test("zlib");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_CCM
case 45:
ret += tcrypt_test("rfc4309(ccm(aes))");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_MD5
case 100:
ret += tcrypt_test("hmac(md5)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_SHA1
case 101:
ret += tcrypt_test("hmac(sha1)");
break;
-
+#endif
case 102:
ret += tcrypt_test("hmac(sha256)");
break;
-
+#ifdef CONFIG_CRYPTO_SHA512
case 103:
ret += tcrypt_test("hmac(sha384)");
break;
@@ -963,15 +1006,16 @@ static int do_test(int m)
case 104:
ret += tcrypt_test("hmac(sha512)");
break;
-
+#endif
case 105:
ret += tcrypt_test("hmac(sha224)");
break;
-
+#ifdef CONFIG_CRYPTO_XCBC
case 106:
ret += tcrypt_test("xcbc(aes)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_RMD
case 107:
ret += tcrypt_test("hmac(rmd128)");
break;
@@ -979,19 +1023,23 @@ static int do_test(int m)
case 108:
ret += tcrypt_test("hmac(rmd160)");
break;
-
+#endif
+#ifdef CONFIG_CRYPTO_VMAC
case 109:
ret += tcrypt_test("vmac(aes)");
break;
-
+#endif
case 150:
ret += tcrypt_test("ansi_cprng");
break;
+#ifdef CONFIG_CRYPTO_GCM
case 151:
ret += tcrypt_test("rfc4106(gcm(aes))");
break;
+#endif
+#ifdef CRYPTO_SPEED_TESTS
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32);
@@ -1230,7 +1278,7 @@ static int do_test(int m)
case 499:
break;
-
+#endif
case 1000:
test_available();
break;
@@ -1248,6 +1296,7 @@ static int do_alg_test(const char *alg, u32 type, u32 mask)
static int __init tcrypt_mod_init(void)
{
int err = -ENOMEM;
+#ifdef CRYPTO_SPEED_TESTS
int i;
for (i = 0; i < TVMEMSIZE; i++) {
@@ -1255,6 +1304,9 @@ static int __init tcrypt_mod_init(void)
if (!tvmem[i])
goto err_free_tv;
}
+#endif
+
+ testmgr_crypto_proc_init();
if (alg)
err = do_alg_test(alg, type, mask);
@@ -1264,8 +1316,12 @@ static int __init tcrypt_mod_init(void)
if (err) {
printk(KERN_ERR "tcrypt: one or more tests failed!\n");
goto err_free_tv;
+#ifndef CONFIG_CRYPTO_FIPS
}
-
+#else
+ } else
+ do_integrity_check();
+#endif
/* We intentionaly return -EAGAIN to prevent keeping the module,
* unless we're running in fips mode. It does all its work from
* init() and doesn't offer any runtime functionality, but in
@@ -1277,9 +1333,10 @@ static int __init tcrypt_mod_init(void)
err = -EAGAIN;
err_free_tv:
+#ifdef CRYPTO_SPEED_TESTS
for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)
free_page((unsigned long)tvmem[i]);
-
+#endif
return err;
}
@@ -1296,10 +1353,11 @@ module_param(alg, charp, 0);
module_param(type, uint, 0);
module_param(mask, uint, 0);
module_param(mode, int, 0);
+#ifdef SUPPORT_SPEED_TEST
module_param(sec, uint, 0);
MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
"(defaults to zero which uses CPU cycles instead)");
-
+#endif
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
diff --git aosp-v3.0/crypto/testmgr.c smdk4210/crypto/testmgr.c
index b6b93d4..3a914c7 100644
--- aosp-v3.0/crypto/testmgr.c
+++ smdk4210/crypto/testmgr.c
@@ -30,7 +30,7 @@
#include "internal.h"
-#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
+#ifndef CONFIG_CRYPTO_MANAGER_TESTS
/* a perfect nop */
int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
@@ -38,6 +38,14 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
return 0;
}
+#ifdef CONFIG_CRYPTO_FIPS
+bool in_fips_err()
+{
+ return false;
+}
+EXPORT_SYMBOL_GPL(in_fips_err);
+#endif
+
#else
#include "testmgr.h"
@@ -65,6 +73,12 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
#define ENCRYPT 1
#define DECRYPT 0
+#ifdef CONFIG_CRYPTO_FIPS
+#define FIPS_ERR 1
+#define FIPS_NO_ERR 0
+static int IN_FIPS_ERROR = FIPS_NO_ERR;
+#endif
+
struct tcrypt_result {
struct completion completion;
int err;
@@ -126,6 +140,19 @@ struct alg_test_desc {
static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
+#ifdef CONFIG_CRYPTO_FIPS
+bool in_fips_err()
+{
+ return (IN_FIPS_ERROR == FIPS_ERR);
+}
+EXPORT_SYMBOL_GPL(in_fips_err);
+
+void set_in_fips_err()
+{
+ IN_FIPS_ERROR = FIPS_ERR;
+}
+#endif
+
static void hexdump(unsigned char *buf, unsigned int len)
{
print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
@@ -1692,7 +1719,9 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "ccm(aes)",
.test = alg_test_aead,
+#ifdef CONFIG_CRYPTO_CCM
.fips_allowed = 1,
+#endif
.suite = {
.aead = {
.enc = {
@@ -2061,7 +2090,9 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "gcm(aes)",
.test = alg_test_aead,
+#ifdef CONFIG_CRYPTO_GCM
.fips_allowed = 1,
+#endif
.suite = {
.aead = {
.enc = {
@@ -2077,7 +2108,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "ghash",
.test = alg_test_hash,
- .fips_allowed = 1,
.suite = {
.hash = {
.vecs = ghash_tv_template,
@@ -2268,6 +2298,9 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "rfc4106(gcm(aes))",
.test = alg_test_aead,
+#ifdef CONFIG_CRYPTO_GCM
+ .fips_allowed = 1,
+#endif
.suite = {
.aead = {
.enc = {
@@ -2285,7 +2318,9 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "rfc4309(ccm(aes))",
.test = alg_test_aead,
+#ifdef CONFIG_CRYPTO_CCM
.fips_allowed = 1,
+#endif
.suite = {
.aead = {
.enc = {
@@ -2530,7 +2565,10 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
{
int i;
int j;
- int rc;
+ int rc = 0;
+#ifdef CONFIG_CRYPTO_FIPS
+ fips_enabled = 1;
+#endif
if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
char nalg[CRYPTO_MAX_ALG_NAME];
@@ -2555,11 +2593,6 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
if (i < 0 && j < 0)
goto notest;
- if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
- (j >= 0 && !alg_test_descs[j].fips_allowed)))
- goto non_fips_alg;
-
- rc = 0;
if (i >= 0)
rc |= alg_test_descs[i].test(alg_test_descs + i, driver,
type, mask);
@@ -2567,23 +2600,52 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
rc |= alg_test_descs[j].test(alg_test_descs + j, driver,
type, mask);
+ if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
+ (j >= 0 && !alg_test_descs[j].fips_allowed)))
+ goto non_fips_alg;
+
test_done:
- if (fips_enabled && rc)
- panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+ if (fips_enabled && rc) {
+ printk(KERN_INFO
+ "FIPS: %s: %s alg self test failed\n",
+ driver, alg);
+#ifdef CONFIG_CRYPTO_FIPS
+ IN_FIPS_ERROR = FIPS_ERR;
+#endif
+ return rc;
+ }
if (fips_enabled && !rc)
- printk(KERN_INFO "alg: self-tests for %s (%s) passed\n",
- driver, alg);
+ printk(KERN_INFO "FIPS: self-tests for %s (%s) passed\n",
+ driver, alg);
return rc;
notest:
- printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+ printk(KERN_INFO "FIPS: No test for %s (%s)\n", alg, driver);
return 0;
non_fips_alg:
- return -EINVAL;
+ if (!rc)
+ printk(KERN_INFO
+ "FIPS: self-tests for non-FIPS %s (%s) passed\n",
+ driver, alg);
+ else
+ printk(KERN_INFO
+ "FIPS: self-tests for non-FIPS %s (%s) failed\n",
+ alg, driver);
+ return rc;
+}
+
+int testmgr_crypto_proc_init(void)
+{
+#ifdef CONFIG_CRYPTO_FIPS
+ crypto_init_proc(&IN_FIPS_ERROR);
+#else
+ crypto_init_proc();
+#endif
+ return 0;
}
-#endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
+#endif /* CONFIG_CRYPTO_MANAGER_TESTS */
EXPORT_SYMBOL_GPL(alg_test);
diff --git aosp-v3.0/drivers/Kconfig smdk4210/drivers/Kconfig
index d0258eb..871235e 100644
--- aosp-v3.0/drivers/Kconfig
+++ smdk4210/drivers/Kconfig
@@ -60,6 +60,8 @@ source "drivers/gpio/Kconfig"
source "drivers/w1/Kconfig"
+source "drivers/battery/Kconfig"
+
source "drivers/power/Kconfig"
source "drivers/hwmon/Kconfig"
@@ -128,4 +130,37 @@ source "drivers/hwspinlock/Kconfig"
source "drivers/clocksource/Kconfig"
+source "drivers/motor/Kconfig"
+
+source "drivers/samsung/Kconfig"
+
+source "drivers/sensor/Kconfig"
+
+source "drivers/sensorhub/Kconfig"
+
+source "drivers/devfreq/Kconfig"
+
+source "drivers/phone_svn/Kconfig"
+
+source "drivers/svnet/Kconfig"
+
+source "drivers/accessory/Kconfig"
+
+source "drivers/irda/Kconfig"
+
+source "drivers/extcon/Kconfig"
+
+source "drivers/barcode_emul/Kconfig"
+
+# Secure OS Mobicore
+source "drivers/gud/Kconfig"
+
+source "drivers/iommu/Kconfig"
+
+# FELICA
+source "drivers/felica/Kconfig"
+
+# Authentec
+source "drivers/interceptor/Kconfig"
+
endmenu
diff --git aosp-v3.0/drivers/Makefile smdk4210/drivers/Makefile
index 4ea4ac9..4c2d947 100644
--- aosp-v3.0/drivers/Makefile
+++ smdk4210/drivers/Makefile
@@ -64,7 +64,7 @@ obj-$(CONFIG_SBUS) += sbus/
obj-$(CONFIG_ZORRO) += zorro/
obj-$(CONFIG_MAC) += macintosh/
obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/
-obj-$(CONFIG_PARIDE) += block/paride/
+obj-$(CONFIG_PARIDE) += block/paride/
obj-$(CONFIG_TC) += tc/
obj-$(CONFIG_UWB) += uwb/
obj-$(CONFIG_USB_OTG_UTILS) += usb/
@@ -80,13 +80,18 @@ obj-y += i2c/ media/
obj-$(CONFIG_PPS) += pps/
obj-$(CONFIG_PTP_1588_CLOCK) += ptp/
obj-$(CONFIG_W1) += w1/
+obj-$(CONFIG_POWER_SUPPLY) += battery/
obj-$(CONFIG_POWER_SUPPLY) += power/
obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_THERMAL) += thermal/
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
+ifeq ($(CONFIG_BT_TIZEN),y)
+obj-$(CONFIG_BT) += bluetooth_tizen/
+else
obj-$(CONFIG_BT) += bluetooth/
+endif
obj-$(CONFIG_ACCESSIBILITY) += accessibility/
obj-$(CONFIG_ISDN) += isdn/
obj-$(CONFIG_EDAC) += edac/
@@ -121,5 +126,29 @@ obj-y += platform/
obj-y += ieee802154/
#common clk code
obj-y += clk/
-
obj-$(CONFIG_HWSPINLOCK) += hwspinlock/
+obj-$(CONFIG_VIBETONZ) += motor/
+
+obj-$(CONFIG_SENSORS_CORE) += sensor/
+obj-$(CONFIG_SENSORS_SSP) += sensorhub/
+obj-$(CONFIG_FM_RADIO) += samsung/
+obj-$(CONFIG_PM_DEVFREQ) += devfreq/
+obj-$(CONFIG_SAMSUNG_PHONE_SVNET) += svnet/
+obj-$(CONFIG_PHONE_IPC_SPI) += phone_svn/
+obj-$(CONFIG_ACCESSORY) += accessory/
+obj-$(CONFIG_IR_REMOCON) += irda/
+obj-$(CONFIG_BARCODE_EMUL) += barcode_emul/
+obj-$(CONFIG_EXTCON) += extcon/
+# Secure OS Mobicore
+obj-$(CONFIG_MOBICORE_SUPPORT) += gud/
+
+obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
+
+obj-$(CONFIG_FELICA) += felica/
+
+obj-$(CONFIG_AUTHENTEC_VPNCLIENT_INTERCEPTOR) += interceptor/
+
+ifeq (1, $(shell if [ -d ./drivers/exfat ]; then echo 1; fi))
+obj-y += exfat/
+endif
+
diff --git aosp-v3.0/drivers/base/Kconfig smdk4210/drivers/base/Kconfig
index 13305c8..e960312 100644
--- aosp-v3.0/drivers/base/Kconfig
+++ smdk4210/drivers/base/Kconfig
@@ -168,6 +168,16 @@ config SYS_HYPERVISOR
bool
default n
+config DMA_SHARED_BUFFER
+ bool "Buffer framework to be shared between drivers"
+ default n
+ depends on ANON_INODES
+ help
+ This option enables the framework for buffer-sharing between
+ multiple drivers. A buffer is associated with a file using driver
+ APIs extension; the file's descriptor can then be passed on to other
+ driver.
+
config SYNC
bool "Synchronization framework"
default n
@@ -194,4 +204,93 @@ config SW_SYNC_USER
Provides a user space API to the sw sync object.
*WARNING* improper use of this can result in deadlocking kernel
drivers from userspace.
+
+config DMA_CMA
+ bool "Contiguous Memory Allocator (EXPERIMENTAL)"
+ default n
+ select MIGRATION
+ help
+ This enables the Contiguous Memory Allocator which allows drivers
+ to allocate big physically-contiguous blocks of memory for use with
+ hardware components that do not support I/O map nor scatter-gather.
+
+ For more information see <include/linux/dma-contiguous.h>.
+ If unsure, say "n".
+
+if DMA_CMA
+
+config DMA_CMA_DEBUG
+ bool "NEW CMA debug messages (DEVELOPMENT)"
+ depends on DEBUG_KERNEL
+ help
+ Turns on debug messages in CMA. This produces KERN_DEBUG
+ messages for every CMA call as well as various messages while
+ processing calls such as dma_alloc_from_contiguous().
+ This option does not affect warning and error messages.
+
+comment "Default contiguous memory area size:"
+
+config CMA_SIZE_MBYTES
+ int "Size in Mega Bytes"
+ depends on !CMA_SIZE_SEL_PERCENTAGE
+ default 16
+ help
+ Defines the size (in MiB) of the default memory area for CMA.
+
+config CMA_SIZE_PERCENTAGE
+ int "Percentage of total memory"
+ depends on !CMA_SIZE_SEL_MBYTES
+ default 10
+ help
+ Defines the size of the default memory area for Contiguous Memory
+ Allocator as a percentage of the total memory in the system.
+
+choice
+ prompt "Selected region size"
+ default CMA_SIZE_SEL_ABSOLUTE
+
+config CMA_SIZE_SEL_MBYTES
+ bool "Use mega bytes value only"
+
+config CMA_SIZE_SEL_PERCENTAGE
+ bool "Use percentage value only"
+
+config CMA_SIZE_SEL_MIN
+ bool "Use lower value (minimum)"
+
+config CMA_SIZE_SEL_MAX
+ bool "Use higher value (maximum)"
+
+endchoice
+
+config CMA_ALIGNMENT
+ int "Maximum PAGE_SIZE order of alignment for contiguous buffers"
+ range 4 9
+ default 8
+ help
+ DMA mapping framework by default aligns all buffers to the smallest
+ PAGE_SIZE order which is greater than or equal to the requested buffer
+ size. This works well for buffers up to a few hundreds kilobytes, but
+ for larger buffers it just a memory waste. With this parameter you can
+ specify the maximum PAGE_SIZE order for contiguous buffers. Larger
+ buffers will be aligned only to this specified order. The order is
+ expressed as a power of two multiplied by the PAGE_SIZE.
+
+ For example, if your system defaults to 4KiB pages, the order value
+ of 8 means that the buffers will be aligned up to 1MiB only.
+
+ If unsure, leave the default value "8".
+
+config CMA_AREAS
+ int "Maximum count of the CMA device-private areas"
+ default 7
+ help
+ CMA allows to create CMA areas for particular devices. This parameter
+ sets the maximum number of such device private CMA areas in the
+ system.
+
+ If unsure, leave the default value "7".
+
+endif
+
endmenu
diff --git aosp-v3.0/drivers/base/Makefile smdk4210/drivers/base/Makefile
index b616882..a60d7e2 100644
--- aosp-v3.0/drivers/base/Makefile
+++ smdk4210/drivers/base/Makefile
@@ -5,15 +5,17 @@ obj-y := core.o sys.o bus.o dd.o syscore.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
+obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
+obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
obj-$(CONFIG_SMP) += topology.o
-obj-$(CONFIG_IOMMU_API) += iommu.o
+obj-$(CONFIG_IOMMU_EXYNOS4_API) += s5p-iommu.o
ifeq ($(CONFIG_SYSFS),y)
obj-$(CONFIG_MODULES) += module.o
endif
diff --git aosp-v3.0/drivers/base/core.c smdk4210/drivers/base/core.c
index d13851c..68bd89e 100644
--- aosp-v3.0/drivers/base/core.c
+++ smdk4210/drivers/base/core.c
@@ -1748,6 +1748,19 @@ void device_shutdown(void)
pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
+#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_PX) || defined(CONFIG_MACH_MIDAS)
+ /* Temporary log to analyze a problem during shutdown */
+ if (dev->bus && dev->bus->shutdown) {
+ dev_info(dev, "shutdown +: %pF\n", dev->bus->shutdown);
+ dev->bus->shutdown(dev);
+ dev_info(dev, "shutdown -\n");
+ } else if (dev->driver && dev->driver->shutdown) {
+ dev_info(dev, "shutdown +: %pF\n",
+ dev->driver->shutdown);
+ dev->driver->shutdown(dev);
+ dev_info(dev, "shutdown -\n");
+ }
+#else
if (dev->bus && dev->bus->shutdown) {
dev_dbg(dev, "shutdown\n");
dev->bus->shutdown(dev);
@@ -1755,6 +1768,7 @@ void device_shutdown(void)
dev_dbg(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
+#endif
put_device(dev);
spin_lock(&devices_kset->list_lock);
diff --git aosp-v3.0/drivers/base/platform.c smdk4210/drivers/base/platform.c
index 6040717..3492df3 100644
--- aosp-v3.0/drivers/base/platform.c
+++ smdk4210/drivers/base/platform.c
@@ -717,8 +717,11 @@ int platform_pm_suspend_noirq(struct device *dev)
return 0;
if (drv->pm) {
- if (drv->pm->suspend_noirq)
+ if (drv->pm->suspend_noirq) {
+ printk(KERN_DEBUG "%s: %s+\n", __func__, dev_name(dev));
ret = drv->pm->suspend_noirq(dev);
+ printk(KERN_DEBUG "%s: %s-\n", __func__, dev_name(dev));
+ }
}
return ret;
diff --git aosp-v3.0/drivers/base/power/main.c smdk4210/drivers/base/power/main.c
index 4282d44..e7de161 100644
--- aosp-v3.0/drivers/base/power/main.c
+++ smdk4210/drivers/base/power/main.c
@@ -428,6 +428,16 @@ static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
static int device_resume_noirq(struct device *dev, pm_message_t state)
{
int error = 0;
+ struct timer_list timer;
+ struct dpm_drv_wd_data data;
+
+ data.dev = dev;
+ data.tsk = get_current();
+ init_timer_on_stack(&timer);
+ timer.expires = jiffies + HZ * 12;
+ timer.function = dpm_drv_timeout;
+ timer.data = (unsigned long)&data;
+ add_timer(&timer);
TRACE_DEVICE(dev);
TRACE_RESUME(0);
@@ -446,6 +456,9 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
error = pm_noirq_op(dev, dev->bus->pm, state);
}
+ del_timer_sync(&timer);
+ destroy_timer_on_stack(&timer);
+
TRACE_RESUME(error);
return error;
}
@@ -512,11 +525,22 @@ static int legacy_resume(struct device *dev, int (*cb)(struct device *dev))
static int device_resume(struct device *dev, pm_message_t state, bool async)
{
int error = 0;
+ struct timer_list timer;
+ struct dpm_drv_wd_data data;
TRACE_DEVICE(dev);
TRACE_RESUME(0);
dpm_wait(dev->parent, async);
+
+ data.dev = dev;
+ data.tsk = get_current();
+ init_timer_on_stack(&timer);
+ timer.expires = jiffies + HZ * 12;
+ timer.function = dpm_drv_timeout;
+ timer.data = (unsigned long)&data;
+ add_timer(&timer);
+
device_lock(dev);
/*
@@ -567,6 +591,10 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
Unlock:
device_unlock(dev);
+
+ del_timer_sync(&timer);
+ destroy_timer_on_stack(&timer);
+
complete_all(&dev->power.completion);
TRACE_RESUME(error);
@@ -773,31 +801,45 @@ static pm_message_t resume_event(pm_message_t sleep_state)
*/
static int device_suspend_noirq(struct device *dev, pm_message_t state)
{
- int error;
+ int error = 0;
+ struct timer_list timer;
+ struct dpm_drv_wd_data data;
+
+ data.dev = dev;
+ data.tsk = get_current();
+ init_timer_on_stack(&timer);
+ timer.expires = jiffies + HZ * 12;
+ timer.function = dpm_drv_timeout;
+ timer.data = (unsigned long)&data;
+ add_timer(&timer);
if (dev->pwr_domain) {
pm_dev_dbg(dev, state, "LATE power domain ");
error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
if (error)
- return error;
+ goto exit;
} else if (dev->type && dev->type->pm) {
pm_dev_dbg(dev, state, "LATE type ");
error = pm_noirq_op(dev, dev->type->pm, state);
if (error)
- return error;
+ goto exit;
} else if (dev->class && dev->class->pm) {
pm_dev_dbg(dev, state, "LATE class ");
error = pm_noirq_op(dev, dev->class->pm, state);
if (error)
- return error;
+ goto exit;
} else if (dev->bus && dev->bus->pm) {
pm_dev_dbg(dev, state, "LATE ");
error = pm_noirq_op(dev, dev->bus->pm, state);
if (error)
- return error;
+ goto exit;
}
- return 0;
+exit:
+ del_timer_sync(&timer);
+ destroy_timer_on_stack(&timer);
+
+ return error;
}
/**
@@ -890,10 +932,12 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
if (async_error)
goto Unlock;
+#ifndef CONFIG_SLP
if (pm_wakeup_pending()) {
async_error = -EBUSY;
goto Unlock;
}
+#endif
if (dev->pwr_domain) {
pm_dev_dbg(dev, state, "power domain ");
@@ -975,6 +1019,9 @@ static int device_suspend(struct device *dev)
* dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
* @state: PM transition of the system being carried out.
*/
+#ifdef CONFIG_FAST_BOOT
+extern bool fake_shut_down;
+#endif
int dpm_suspend(pm_message_t state)
{
ktime_t starttime = ktime_get();
@@ -996,8 +1043,18 @@ int dpm_suspend(pm_message_t state)
mutex_lock(&dpm_list_mtx);
if (error) {
pm_dev_err(dev, state, "", error);
+#ifdef CONFIG_FAST_BOOT
+ if (fake_shut_down) {
+ pr_info("%s: fake shut down\n", __func__);
+ error = 0;
+ } else {
+ put_device(dev);
+ break;
+ }
+#else
put_device(dev);
break;
+#endif
}
if (!list_empty(&dev->power.entry))
list_move(&dev->power.entry, &dpm_suspended_list);
diff --git aosp-v3.0/drivers/base/power/opp.c smdk4210/drivers/base/power/opp.c
index 56a6899..335e9dd 100644
--- aosp-v3.0/drivers/base/power/opp.c
+++ smdk4210/drivers/base/power/opp.c
@@ -73,6 +73,7 @@ struct opp {
* RCU usage: nodes are not modified in the list of device_opp,
* however addition is possible and is secured by dev_opp_list_lock
* @dev: device pointer
+ * @head: notifier head to notify the OPP availability changes.
* @opp_list: list of opps
*
* This is an internal data structure maintaining the link to opps attached to
@@ -83,6 +84,7 @@ struct device_opp {
struct list_head node;
struct device *dev;
+ struct srcu_notifier_head head;
struct list_head opp_list;
};
@@ -404,6 +406,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
}
dev_opp->dev = dev;
+ srcu_init_notifier_head(&dev_opp->head);
INIT_LIST_HEAD(&dev_opp->opp_list);
/* Secure the device list modification */
@@ -428,6 +431,11 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
list_add_rcu(&new_opp->node, head);
mutex_unlock(&dev_opp_list_lock);
+ /*
+ * Notify the changes in the availability of the operable
+ * frequency/voltage list.
+ */
+ srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ADD, new_opp);
return 0;
}
@@ -453,7 +461,7 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
static int opp_set_availability(struct device *dev, unsigned long freq,
bool availability_req)
{
- struct device_opp *tmp_dev_opp, *dev_opp = NULL;
+ struct device_opp *tmp_dev_opp, *dev_opp = ERR_PTR(-ENODEV);
struct opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV);
int r = 0;
@@ -504,6 +512,14 @@ static int opp_set_availability(struct device *dev, unsigned long freq,
mutex_unlock(&dev_opp_list_lock);
synchronize_rcu();
+ /* Notify the change of the OPP availability */
+ if (availability_req)
+ srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_ENABLE,
+ new_opp);
+ else
+ srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE,
+ new_opp);
+
/* clean up old opp */
new_opp = opp;
goto out;
@@ -626,3 +642,17 @@ int opp_init_cpufreq_table(struct device *dev,
return 0;
}
#endif /* CONFIG_CPU_FREQ */
+
+/**
+ * opp_get_notifier() - find notifier_head of the device with opp
+ * @dev: device pointer used to lookup device OPPs.
+ */
+struct srcu_notifier_head *opp_get_notifier(struct device *dev)
+{
+ struct device_opp *dev_opp = find_device_opp(dev);
+
+ if (IS_ERR(dev_opp))
+ return ERR_CAST(dev_opp); /* matching type */
+
+ return &dev_opp->head;
+}
diff --git aosp-v3.0/drivers/base/power/runtime.c smdk4210/drivers/base/power/runtime.c
index 184cf54..4d21044 100644
--- aosp-v3.0/drivers/base/power/runtime.c
+++ smdk4210/drivers/base/power/runtime.c
@@ -964,6 +964,9 @@ int pm_runtime_barrier(struct device *dev)
{
int retval = 0;
+#ifdef CONFIG_MDM_HSIC_PM
+ wake_up_all(&dev->power.wait_queue);
+#endif
pm_runtime_get_noresume(dev);
spin_lock_irq(&dev->power.lock);
diff --git aosp-v3.0/drivers/bluetooth/hci_ldisc.c smdk4210/drivers/bluetooth/hci_ldisc.c
index 8f3d6db..1d939b2 100644
--- aosp-v3.0/drivers/bluetooth/hci_ldisc.c
+++ smdk4210/drivers/bluetooth/hci_ldisc.c
@@ -90,6 +90,12 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
{
struct hci_dev *hdev = hu->hdev;
+#if defined(CONFIG_BT_CSR8811)
+ if(hdev == NULL)
+ return ;
+#endif
+
+
/* Update HCI stat counters */
switch (pkt_type) {
case HCI_COMMAND_PKT:
@@ -124,6 +130,11 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
struct hci_dev *hdev = hu->hdev;
struct sk_buff *skb;
+#if defined(CONFIG_BT_CSR8811)
+ if(hdev == NULL)
+ return -1;
+#endif
+
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
return 0;
@@ -136,6 +147,13 @@ restart:
while ((skb = hci_uart_dequeue(hu))) {
int len;
+/* Samsung Bluetooth Feature.2012.01.19
+ * Add wake_peer uart operation which is called before starting UART TX
+ */
+#if !defined(CONFIG_BT_CSR8811)
+ if (hdev->wake_peer)
+ hdev->wake_peer(hdev);
+#endif
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
len = tty->ops->write(tty, skb->data, skb->len);
@@ -331,6 +349,11 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
{
struct hci_uart *hu = (void *)tty->disc_data;
+#if defined(CONFIG_BT_CSR8811)
+ if(hu->hdev == NULL)
+ return ;
+#endif
+
BT_DBG("");
if (!hu)
@@ -361,12 +384,22 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
{
struct hci_uart *hu = (void *)tty->disc_data;
+#if defined(CONFIG_BT_CSR8811)
+ if(hu->hdev == NULL)
+ return ;
+#endif
+
if (!hu || tty != hu->tty)
return;
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
return;
+/* CSR8811 Project(Dayton.Kim) 2012.02.23 */
+ if (hu == NULL || hu->proto == NULL || hu->proto->recv == NULL || data == NULL)
+ return;
+/* CSR8811 Project(Dayton.Kim) end */
+
spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count;
@@ -381,6 +414,8 @@ static int hci_uart_register_dev(struct hci_uart *hu)
BT_DBG("");
+ BT_ERR("hci_uart_register_dev");
+
/* Initialize and register HCI device */
hdev = hci_alloc_dev();
if (!hdev) {
@@ -508,16 +543,141 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
/*
* We don't provide read/write/poll interface for user space.
*/
+struct hci_uart_hook {
+ unsigned int len;
+ unsigned char *head;
+ unsigned char data[HCI_MAX_EVENT_SIZE + 1]; /* save packet type at data[0] and then place event packet */
+};
+
+static struct hci_uart_hook *hook;
+static DECLARE_WAIT_QUEUE_HEAD(read_wait);
+
+void hci_uart_tty_read_hook(struct sk_buff *skb)
+{
+ if (!hook) {
+ BT_DBG("%s: hooking wasn't requested, skip it", __func__);
+ goto hci_uart_tty_read_hook_exit;
+ }
+
+ if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT) {
+ BT_DBG("%s: Packet type is %d, skip it", __func__, bt_cb(skb)->pkt_type);
+ goto hci_uart_tty_read_hook_exit;
+ }
+
+ BT_DBG("%s: Received len = %d", __func__, skb->len);
+ if (skb->len > sizeof(hook->data)-1) {
+ BT_DBG("Packet size exceeds max len, skip it");
+ goto hci_uart_tty_read_hook_exit;
+ }
+
+ memcpy(hook->data, &bt_cb(skb)->pkt_type, 1);
+ skb_copy_from_linear_data(skb, &hook->data[1], skb->len);
+ hook->len = skb->len + 1;
+
+hci_uart_tty_read_hook_exit:
+ wake_up_interruptible(&read_wait);
+}
+EXPORT_SYMBOL(hci_uart_tty_read_hook);
+
+static int hci_uart_tty_access_allowed(void)
+{
+ char name[TASK_COMM_LEN];
+ get_task_comm(name, current_thread_info()->task);
+ BT_DBG("%s: %s", __func__, name);
+ if (strcmp(name, "brcm_poke_helpe")) {
+ BT_ERR("%s isn't allowed", name);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr)
{
- return 0;
+ struct hci_uart *hu = (void *) tty->disc_data;
+ struct hci_dev *hdev = hu->hdev;
+ int ret = 0, count;
+
+ BT_DBG("%s: hu = 0x%p hci_dev = 0x%p, nr = %d", __func__, hu, hdev, nr);
+
+ ret = hci_uart_tty_access_allowed();
+ if (ret < 0)
+ return ret;
+
+ if (!hook)
+ return -ENOMEM;
+
+ if (!hook->len)
+ interruptible_sleep_on_timeout(&read_wait, 3 * HZ);
+
+ if (!hook->len) {
+ BT_INFO("No data to read");
+ } else {
+ count = nr > hook->len ? hook->len : nr;
+
+ ret = copy_to_user(buf, hook->head, count);
+
+ hook->len -= (count - ret);
+ hook->head += (count - ret);
+
+ ret = count - ret;
+ }
+
+ if (!hook->len) {
+ BT_DBG("%s: free hook", __func__);
+ kfree(hook);
+ hook = NULL;
+ }
+
+ BT_DBG("%s: ret = %d", __func__, ret);
+
+ return ret;
}
static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file,
const unsigned char *data, size_t count)
{
- return 0;
+ struct hci_uart *hu = (void *) tty->disc_data;
+ struct hci_dev *hdev = hu->hdev;
+ int ret;
+
+ BT_DBG("%s: hu = 0x%p, hci_dev = 0x%p", __func__, hu, hdev);
+
+ ret = hci_uart_tty_access_allowed();
+ if (ret < 0)
+ return ret;
+
+ if (!hdev)
+ return -ENODEV;
+
+ if (!hook)
+ hook = kzalloc(sizeof(*hook), GFP_KERNEL);
+ else {
+ /* Cuase brcm_poke_helper's read/write is serialized,
+ * it's almost safe to init hook data here
+ */
+ BT_INFO("hook data still remains");
+ memset(hook, 0, sizeof(*hook));
+ }
+
+ if (!hook)
+ return -ENOMEM;
+
+ hook->head = hook->data;
+
+ hci_uart_flush(hdev);
+
+#if 1
+ if (hdev->wake_peer)
+ hdev->wake_peer(hdev);
+#endif
+
+ ret = tty->ops->write(tty, data, count);
+
+ BT_DBG("%s: ret = %d", __func__, ret);
+
+ return ret;
}
static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
diff --git aosp-v3.0/drivers/char/Kconfig smdk4210/drivers/char/Kconfig
index 7d10ae3..ea75975 100644
--- aosp-v3.0/drivers/char/Kconfig
+++ smdk4210/drivers/char/Kconfig
@@ -64,6 +64,8 @@ config SGI_MBCS
source "drivers/tty/serial/Kconfig"
+source "drivers/char/diag/Kconfig"
+
config TTY_PRINTK
bool "TTY driver to output user messages via printk"
depends on EXPERT
@@ -625,6 +627,22 @@ config RAMOOPS
This enables panic and oops messages to be logged to a circular
buffer in RAM where it can be read back at some later point.
+config S3C_MEM
+ bool "Support for /dev/s3c-mem"
+ default y
+ ---help---
+ If you do say Y here, you can allocate physically linear memories from system memory.
+ And you can share the memory at the other process using re-allocation ioctl.
+
+ If unsure, say Y.
+
+config EXYNOS_MEM
+ bool "Support for /dev/exynos-mem"
+ default y
+ help
+ If you do say Y here, you can mmap using physically linear memories.
+ And you can flush it using ioctl.
+
config MSM_SMD_PKT
bool "Enable device interface for some SMD packet ports"
default n
diff --git aosp-v3.0/drivers/char/Makefile smdk4210/drivers/char/Makefile
index 3f63254..fe23295 100644
--- aosp-v3.0/drivers/char/Makefile
+++ smdk4210/drivers/char/Makefile
@@ -64,3 +64,8 @@ obj-$(CONFIG_RAMOOPS) += ramoops.o
obj-$(CONFIG_JS_RTC) += js-rtc.o
js-rtc-y = rtc.o
+
+obj-$(CONFIG_S3C_MEM) += s3c_mem.o
+obj-$(CONFIG_EXYNOS_MEM) += exynos_mem.o
+
+obj-$(CONFIG_DIAG_CHAR) += diag/
diff --git aosp-v3.0/drivers/char/mem.c smdk4210/drivers/char/mem.c
index 9b1eb18..e40d5d6 100644
--- aosp-v3.0/drivers/char/mem.c
+++ smdk4210/drivers/char/mem.c
@@ -34,6 +34,14 @@
# include <linux/efi.h>
#endif
+#ifdef CONFIG_S3C_MEM
+# include "s3c_mem.h"
+#ifdef CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM
+#include <linux/cma.h>
+#include <linux/platform_device.h>
+#endif
+#endif
+
static inline unsigned long size_inside_page(unsigned long start,
unsigned long size)
{
@@ -821,6 +829,39 @@ static const struct file_operations oldmem_fops = {
};
#endif
+#ifdef CONFIG_S3C_MEM
+extern int s3c_mem_mmap(struct file* filp, struct vm_area_struct *vma);
+extern long s3c_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations s3c_mem_fops = {
+#ifdef CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM
+ .open = s3c_mem_open,
+ .release = s3c_mem_release,
+#endif
+ .unlocked_ioctl = s3c_mem_ioctl,
+ .mmap = s3c_mem_mmap,
+};
+
+#ifdef CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM
+static struct backing_dev_info s3c_mem_cma_dev_bdi;
+#endif
+
+#endif
+
+#ifdef CONFIG_EXYNOS_MEM
+extern int exynos_mem_open(struct inode * inode, struct file *filp);
+extern int exynos_mem_release(struct inode * inode, struct file *filp);
+extern long exynos_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+extern int exynos_mem_mmap(struct file* filp, struct vm_area_struct *vma);
+
+static const struct file_operations exynos_mem_fops = {
+ .open = exynos_mem_open,
+ .release = exynos_mem_release,
+ .unlocked_ioctl = exynos_mem_ioctl,
+ .mmap = exynos_mem_mmap,
+};
+#endif
+
static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
@@ -883,6 +924,19 @@ static const struct memdev {
#ifdef CONFIG_CRASH_DUMP
[12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif
+#ifdef CONFIG_S3C_MEM
+ [13] = {
+ "s3c-mem", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+ | S_IWOTH, &s3c_mem_fops
+#ifdef CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM
+ , &s3c_mem_cma_dev_bdi
+#endif
+ },
+#endif
+#ifdef CONFIG_EXYNOS_MEM
+ [14] = {"exynos-mem", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+ | S_IWOTH, &exynos_mem_fops},
+#endif
};
static int memory_open(struct inode *inode, struct file *filp)
@@ -930,7 +984,9 @@ static int __init chr_dev_init(void)
{
int minor;
int err;
-
+#if defined(CONFIG_S3C_MEM) && defined(CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM)
+ struct device *dev;
+#endif
err = bdi_init(&zero_bdi);
if (err)
return err;
@@ -946,11 +1002,26 @@ static int __init chr_dev_init(void)
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name)
continue;
- device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+#if defined(CONFIG_S3C_MEM) && defined(CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM)
+ dev = device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
NULL, devlist[minor].name);
+
+ if (devlist[minor].dev_info == &s3c_mem_cma_dev_bdi)
+ devlist[minor].dev_info->dev = IS_ERR(dev) ? NULL : dev;
+
+#else
+ device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+ NULL, devlist[minor].name);
+
+#endif
+
}
return tty_init();
}
+#if defined(CONFIG_S3C_MEM) && defined(CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM)
+late_initcall(chr_dev_init);
+#else
fs_initcall(chr_dev_init);
+#endif
diff --git aosp-v3.0/drivers/cpufreq/Kconfig smdk4210/drivers/cpufreq/Kconfig
index 1947088..8112af3a 100644
--- aosp-v3.0/drivers/cpufreq/Kconfig
+++ smdk4210/drivers/cpufreq/Kconfig
@@ -109,6 +109,20 @@ config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
loading your cpufreq low-level hardware driver, using the
'interactive' governor for latency-sensitive workloads.
+config CPU_FREQ_DEFAULT_GOV_ADAPTIVE
+ bool "adaptive"
+ select CPU_FREQ_GOV_ADAPTIVE
+ help
+ Use the CPUFreq governor 'adaptive' as default. This allows
+ you to get a full dynamic cpu frequency capable system by simply
+ loading your cpufreq low-level hardware driver, using the
+ 'adaptive' governor for latency-sensitive workloads and demanding
+ performance.
+
+config CPU_FREQ_DEFAULT_GOV_PEGASUSQ
+ bool "pegasusq"
+ select CPU_FREQ_GOV_PEGASUSQ
+
endchoice
config CPU_FREQ_GOV_PERFORMANCE
@@ -166,6 +180,28 @@ config CPU_FREQ_GOV_ONDEMAND
If in doubt, say N.
+config CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ bool "flexrate interface for 'ondemand' cpufreq policy governor"
+ depends on CPU_FREQ_GOV_ONDEMAND
+ help
+ Flexrate for 'ondemand' governor provides an interface to request
+ faster polling temporarily. This is to let it react quickly to
+ load changes when there is high probablity of load increase
+ in short time. For example, when a user event occurs, we have
+ use this interface. It does not increase the frequency
+ unconditionally; however, it allows ondemand to react fast
+ by temporarily decreasing sampling rate. Flexrate provides both
+ sysfs interface and in-kernel interface.
+
+config CPU_FREQ_GOV_ONDEMAND_FLEXRATE_MAX_DURATION
+ int "flexrate's maximum duration of sampling rate override"
+ range 5 500
+ depends on CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ default "100"
+ help
+ The maximum number of ondemand sampling whose rate is
+ overriden by Flexrate for ondemand.
+
config CPU_FREQ_GOV_INTERACTIVE
tristate "'interactive' cpufreq policy governor"
help
@@ -206,6 +242,49 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.
+config CPU_FREQ_GOV_ADAPTIVE
+ tristate "'adaptive' cpufreq policy governor"
+ help
+ 'adaptive' - This driver adds a dynamic cpufreq policy governor
+ designed for latency-sensitive workloads and also for demanding
+ performance.
+
+ This governor attempts to reduce the latency of clock
+ increases so that the system is more responsive to
+ interactive workloads in loweset steady-state but to
+ to reduce power consumption in middle operation level level up
+ will be done in step by step to prohibit system from going to
+ max operation level.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cpufreq_adaptive.
+
+ For details, take a look at linux/Documentation/cpu-freq.
+
+ If in doubt, say N.
+
+config CPU_FREQ_GOV_PEGASUSQ
+ tristate "'pegasusq' cpufreq policy governor"
+
+config CPU_FREQ_GOV_SLP
+ tristate "'slp' cpufreq policy governor"
+
+config SLP_CHECK_CPU_LOAD
+ bool "check load and frequency of cpu"
+ depends on CPU_FREQ_GOV_SLP
+
+config SLP_GOV_DYNAMIC_PARAMS
+ bool "check SLP GOV. Dynamic Params feature"
+ depends on CPU_FREQ_GOV_SLP
+
+config CPU_FREQ_DVFS_MONITOR
+ bool "dvfs monitor"
+ depends on CPU_FREQ
+ help
+ This option adds a proc node for dvfs monitoring.
+ /proc/dvfs_mon
+
+
menu "x86 CPU frequency scaling drivers"
depends on X86
source "drivers/cpufreq/Kconfig.x86"
diff --git aosp-v3.0/drivers/cpufreq/Makefile smdk4210/drivers/cpufreq/Makefile
index c044060..101c6ed 100644
--- aosp-v3.0/drivers/cpufreq/Makefile
+++ smdk4210/drivers/cpufreq/Makefile
@@ -8,12 +8,17 @@ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
+obj-$(CONFIG_CPU_FREQ_GOV_SLP) += cpufreq_slp.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o
+obj-$(CONFIG_CPU_FREQ_GOV_ADAPTIVE) += cpufreq_adaptive.o
+obj-$(CONFIG_CPU_FREQ_GOV_PEGASUSQ) += cpufreq_pegasusq.o
# CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
+obj-$(CONFIG_CPU_FREQ_DVFS_MONITOR) += dvfs_monitor.o
+
##################################################################################d
# x86 drivers.
# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
diff --git aosp-v3.0/drivers/cpufreq/cpufreq.c smdk4210/drivers/cpufreq/cpufreq.c
index 0a5bea9..9785cf7 100644
--- aosp-v3.0/drivers/cpufreq/cpufreq.c
+++ smdk4210/drivers/cpufreq/cpufreq.c
@@ -189,7 +189,7 @@ EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
* systems as each CPU might be scaled differently. So, use the arch
* per-CPU loops_per_jiffy value wherever possible.
*/
-#ifndef CONFIG_SMP
+#if !defined CONFIG_SMP || defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
static unsigned long l_p_j_ref;
static unsigned int l_p_j_ref_freq;
diff --git aosp-v3.0/drivers/cpufreq/cpufreq_conservative.c smdk4210/drivers/cpufreq/cpufreq_conservative.c
index 33b56e5..8b4ea13 100644
--- aosp-v3.0/drivers/cpufreq/cpufreq_conservative.c
+++ smdk4210/drivers/cpufreq/cpufreq_conservative.c
@@ -29,8 +29,8 @@
* It helps to keep variable names smaller, simpler
*/
-#define DEF_FREQUENCY_UP_THRESHOLD (80)
-#define DEF_FREQUENCY_DOWN_THRESHOLD (20)
+#define DEF_FREQUENCY_UP_THRESHOLD (90)
+#define DEF_FREQUENCY_DOWN_THRESHOLD (40)
/*
* The polling frequency of this governor depends on the capability of
@@ -42,11 +42,11 @@
* this governor will not work.
* All times here are in uS.
*/
-#define MIN_SAMPLING_RATE_RATIO (2)
+#define MIN_SAMPLING_RATE_RATIO (1)
static unsigned int min_sampling_rate;
-#define LATENCY_MULTIPLIER (1000)
+#define LATENCY_MULTIPLIER (500)
#define MIN_LATENCY_MULTIPLIER (100)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10)
@@ -92,7 +92,7 @@ static struct dbs_tuners {
.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
.ignore_nice = 0,
- .freq_step = 5,
+ .freq_step = 10,
};
static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
@@ -532,7 +532,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
* governor, thus we are bound to jiffes/HZ
*/
min_sampling_rate =
- MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
+ MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(5);
/* Bring kernel and HW constraints together */
min_sampling_rate = max(min_sampling_rate,
MIN_LATENCY_MULTIPLIER * latency);
diff --git aosp-v3.0/drivers/cpufreq/cpufreq_interactive.c smdk4210/drivers/cpufreq/cpufreq_interactive.c
index 7e17725..7dbacf0 100644
--- aosp-v3.0/drivers/cpufreq/cpufreq_interactive.c
+++ smdk4210/drivers/cpufreq/cpufreq_interactive.c
@@ -50,6 +50,7 @@ struct cpufreq_interactive_cpuinfo {
unsigned int target_freq;
unsigned int floor_freq;
u64 floor_validate_time;
+ u64 hispeed_validate_time;
int governor_enabled;
};
@@ -207,7 +208,7 @@ static void cpufreq_interactive_timer(unsigned long data)
if (pcpu->target_freq == hispeed_freq &&
new_freq > hispeed_freq &&
cputime64_sub(pcpu->timer_run_time,
- pcpu->target_set_time)
+ pcpu->hispeed_validate_time)
< above_hispeed_delay_val) {
trace_cpufreq_interactive_notyet(data, cpu_load,
pcpu->target_freq,
@@ -219,6 +220,9 @@ static void cpufreq_interactive_timer(unsigned long data)
new_freq = pcpu->policy->max * cpu_load / 100;
}
+ if (new_freq <= hispeed_freq)
+ pcpu->hispeed_validate_time = pcpu->timer_run_time;
+
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
new_freq, CPUFREQ_RELATION_H,
&index)) {
@@ -507,6 +511,7 @@ static void cpufreq_interactive_boost(void)
cpumask_set_cpu(i, &up_cpumask);
pcpu->target_set_time_in_idle =
get_cpu_idle_time_us(i, &pcpu->target_set_time);
+ pcpu->hispeed_validate_time = pcpu->target_set_time;
anyboost = 1;
}
@@ -840,6 +845,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->floor_freq = pcpu->target_freq;
pcpu->floor_validate_time =
pcpu->target_set_time;
+ pcpu->hispeed_validate_time =
+ pcpu->target_set_time;
pcpu->governor_enabled = 1;
smp_wmb();
}
diff --git aosp-v3.0/drivers/cpufreq/cpufreq_ondemand.c smdk4210/drivers/cpufreq/cpufreq_ondemand.c
index 891360e..e151adc 100644
--- aosp-v3.0/drivers/cpufreq/cpufreq_ondemand.c
+++ smdk4210/drivers/cpufreq/cpufreq_ondemand.c
@@ -22,6 +22,7 @@
#include <linux/tick.h>
#include <linux/ktime.h>
#include <linux/sched.h>
+#include <linux/pm_qos_params.h>
/*
* dbs is used in this file as a shortform for demandbased switching
@@ -32,8 +33,15 @@
#define DEF_FREQUENCY_UP_THRESHOLD (80)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (100000)
+
+#if defined(CONFIG_MACH_SLP_PQ)
+#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (5)
+#define MICRO_FREQUENCY_UP_THRESHOLD (85)
+#else
#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3)
#define MICRO_FREQUENCY_UP_THRESHOLD (95)
+#endif
+
#define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000)
#define MIN_FREQUENCY_UP_THRESHOLD (11)
#define MAX_FREQUENCY_UP_THRESHOLD (100)
@@ -77,6 +85,7 @@ struct cpu_dbs_info_s {
cputime64_t prev_cpu_idle;
cputime64_t prev_cpu_iowait;
cputime64_t prev_cpu_wall;
+ unsigned int prev_cpu_wall_delta;
cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
struct delayed_work work;
@@ -93,6 +102,10 @@ struct cpu_dbs_info_s {
* when user is changing the governor or limits.
*/
struct mutex timer_mutex;
+ bool activated; /* dbs_timer_init is in effect */
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ unsigned int flex_duration;
+#endif
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
@@ -102,6 +115,9 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
* dbs_mutex protects dbs_enable in governor start/stop.
*/
static DEFINE_MUTEX(dbs_mutex);
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+static DEFINE_MUTEX(flex_mutex);
+#endif
static struct dbs_tuners {
unsigned int sampling_rate;
@@ -111,12 +127,20 @@ static struct dbs_tuners {
unsigned int sampling_down_factor;
unsigned int powersave_bias;
unsigned int io_is_busy;
+ struct notifier_block dvfs_lat_qos_db;
+ unsigned int dvfs_lat_qos_wants;
+ unsigned int freq_step;
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ unsigned int flex_sampling_rate;
+ unsigned int flex_duration;
+#endif
} dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
.down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
.ignore_nice = 0,
.powersave_bias = 0,
+ .freq_step = 100,
};
static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
@@ -163,6 +187,23 @@ static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wal
}
/*
+ * Find right sampling rate based on sampling_rate and
+ * QoS requests on dvfs latency.
+ */
+static unsigned int effective_sampling_rate(void)
+{
+ unsigned int effective;
+
+ if (dbs_tuners_ins.dvfs_lat_qos_wants)
+ effective = min(dbs_tuners_ins.dvfs_lat_qos_wants,
+ dbs_tuners_ins.sampling_rate);
+ else
+ effective = dbs_tuners_ins.sampling_rate;
+
+ return max(effective, min_sampling_rate);
+}
+
+/*
* Find right freq to be set now with powersave_bias on.
* Returns the freq_hi to be used right now and will set freq_hi_jiffies,
* freq_lo, and freq_lo_jiffies in percpu area for averaging freqs.
@@ -206,7 +247,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
dbs_info->freq_lo_jiffies = 0;
return freq_lo;
}
- jiffies_total = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ jiffies_total = usecs_to_jiffies(effective_sampling_rate());
jiffies_hi = (freq_avg - freq_lo) * jiffies_total;
jiffies_hi += ((freq_hi - freq_lo) / 2);
jiffies_hi /= (freq_hi - freq_lo);
@@ -255,6 +296,95 @@ show_one(up_threshold, up_threshold);
show_one(sampling_down_factor, sampling_down_factor);
show_one(ignore_nice_load, ignore_nice);
show_one(powersave_bias, powersave_bias);
+show_one(down_differential, down_differential);
+show_one(freq_step, freq_step);
+
+/**
+ * update_sampling_rate - update sampling rate effective immediately if needed.
+ * @new_rate: new sampling rate. If it is 0, regard sampling rate is not
+ * changed and assume that qos request value is changed.
+ *
+ * If new rate is smaller than the old, simply updaing
+ * dbs_tuners_int.sampling_rate might not be appropriate. For example,
+ * if the original sampling_rate was 1 second and the requested new sampling
+ * rate is 10 ms because the user needs immediate reaction from ondemand
+ * governor, but not sure if higher frequency will be required or not,
+ * then, the governor may change the sampling rate too late; up to 1 second
+ * later. Thus, if we are reducing the sampling rate, we need to make the
+ * new value effective immediately.
+ */
+static void update_sampling_rate(unsigned int new_rate)
+{
+ int cpu;
+ unsigned int effective;
+
+ if (new_rate)
+ dbs_tuners_ins.sampling_rate = max(new_rate, min_sampling_rate);
+
+ effective = effective_sampling_rate();
+
+ for_each_online_cpu(cpu) {
+ struct cpufreq_policy *policy;
+ struct cpu_dbs_info_s *dbs_info;
+ unsigned long next_sampling, appointed_at;
+
+ /*
+ * mutex_destory(&dbs_info->timer_mutex) should not happen
+ * in this context. dbs_mutex is locked/unlocked at GOV_START
+ * and GOV_STOP context only other than here.
+ */
+ mutex_lock(&dbs_mutex);
+
+ policy = cpufreq_cpu_get(cpu);
+ if (!policy) {
+ mutex_unlock(&dbs_mutex);
+ continue;
+ }
+ dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu);
+ cpufreq_cpu_put(policy);
+
+ /* timer_mutex is destroyed or will be destroyed soon */
+ if (!dbs_info->activated) {
+ mutex_unlock(&dbs_mutex);
+ continue;
+ }
+
+ mutex_lock(&dbs_info->timer_mutex);
+
+ if (!delayed_work_pending(&dbs_info->work)) {
+ mutex_unlock(&dbs_info->timer_mutex);
+ mutex_unlock(&dbs_mutex);
+ continue;
+ }
+
+ next_sampling = jiffies + usecs_to_jiffies(new_rate);
+ appointed_at = dbs_info->work.timer.expires;
+
+ if (time_before(next_sampling, appointed_at)) {
+ mutex_unlock(&dbs_info->timer_mutex);
+ cancel_delayed_work_sync(&dbs_info->work);
+ mutex_lock(&dbs_info->timer_mutex);
+
+ schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work,
+ usecs_to_jiffies(effective));
+ }
+ mutex_unlock(&dbs_info->timer_mutex);
+
+ /*
+ * For the little possiblity that dbs_timer_exit() has been
+ * called after checking dbs_info->activated above.
+ * If cancel_delayed_work_syn() has been calld by
+ * dbs_timer_exit() before schedule_delayed_work_on() of this
+ * function, it should be revoked by calling cancel again
+ * before releasing dbs_mutex, which will trigger mutex_destroy
+ * to be called.
+ */
+ if (!dbs_info->activated)
+ cancel_delayed_work_sync(&dbs_info->work);
+
+ mutex_unlock(&dbs_mutex);
+ }
+}
static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
@@ -264,7 +394,7 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
- dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
+ update_sampling_rate(input);
return count;
}
@@ -367,12 +497,46 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
return count;
}
+static ssize_t store_down_differential(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+ dbs_tuners_ins.down_differential = min(input, 100u);
+ return count;
+}
+
+static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+ dbs_tuners_ins.freq_step = min(input, 100u);
+ return count;
+}
+
+
define_one_global_rw(sampling_rate);
define_one_global_rw(io_is_busy);
define_one_global_rw(up_threshold);
define_one_global_rw(sampling_down_factor);
define_one_global_rw(ignore_nice_load);
define_one_global_rw(powersave_bias);
+define_one_global_rw(down_differential);
+define_one_global_rw(freq_step);
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+static struct global_attr flexrate_request;
+static struct global_attr flexrate_duration;
+static struct global_attr flexrate_enable;
+static struct global_attr flexrate_forcerate;
+static struct global_attr flexrate_num_effective_usage;
+#endif
static struct attribute *dbs_attributes[] = {
&sampling_rate_min.attr,
@@ -382,6 +546,15 @@ static struct attribute *dbs_attributes[] = {
&ignore_nice_load.attr,
&powersave_bias.attr,
&io_is_busy.attr,
+ &down_differential.attr,
+ &freq_step.attr,
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ &flexrate_request.attr,
+ &flexrate_duration.attr,
+ &flexrate_enable.attr,
+ &flexrate_forcerate.attr,
+ &flexrate_num_effective_usage.attr,
+#endif
NULL
};
@@ -396,8 +569,10 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
{
if (dbs_tuners_ins.powersave_bias)
freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
+#if !defined(CONFIG_ARCH_EXYNOS4) && !defined(CONFIG_ARCH_EXYNOS5)
else if (p->cur == p->max)
return;
+#endif
__cpufreq_driver_target(p, freq, dbs_tuners_ins.powersave_bias ?
CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
@@ -434,6 +609,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
unsigned int idle_time, wall_time, iowait_time;
unsigned int load, load_freq;
int freq_avg;
+ bool deep_sleep_detected = false;
+ /* the evil magic numbers, only 2 at least */
+ const unsigned int deep_sleep_backoff = 10;
+ const unsigned int deep_sleep_factor = 5;
j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
@@ -444,6 +623,32 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
j_dbs_info->prev_cpu_wall);
j_dbs_info->prev_cpu_wall = cur_wall_time;
+ /*
+ * Ignore wall delta jitters in both directions. An
+ * exceptionally long wall_time will likely result
+ * idle but it was waken up to do work so the next
+ * slice is less likely to want to run at low
+ * frequency. Let's evaluate the next slice instead of
+ * the idle long one that passed already and it's too
+ * late to reduce in frequency. As opposed an
+ * exceptionally short slice that just run at low
+ * frequency is unlikely to be idle, but we may go
+ * back to idle pretty soon and that not idle slice
+ * already passed. If short slices will keep coming
+ * after a series of long slices the exponential
+ * backoff will converge faster and we'll react faster
+ * to high load. As opposed we'll decay slower
+ * towards low load and long idle times.
+ */
+ if (j_dbs_info->prev_cpu_wall_delta >
+ wall_time * deep_sleep_factor ||
+ j_dbs_info->prev_cpu_wall_delta * deep_sleep_factor <
+ wall_time)
+ deep_sleep_detected = true;
+ j_dbs_info->prev_cpu_wall_delta =
+ (j_dbs_info->prev_cpu_wall_delta * deep_sleep_backoff
+ + wall_time) / (deep_sleep_backoff+1);
+
idle_time = (unsigned int) cputime64_sub(cur_idle_time,
j_dbs_info->prev_cpu_idle);
j_dbs_info->prev_cpu_idle = cur_idle_time;
@@ -469,6 +674,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
idle_time += jiffies_to_usecs(cur_nice_jiffies);
}
+ if (deep_sleep_detected)
+ continue;
+
/*
* For the purpose of ondemand, waiting for disk IO is an
* indication that you're performance critical, and not that
@@ -495,18 +703,22 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
/* Check for frequency increase */
if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) {
+ int inc = (policy->max * dbs_tuners_ins.freq_step) / 100;
+ int target = min(policy->max, policy->cur + inc);
/* If switching to max speed, apply sampling_down_factor */
- if (policy->cur < policy->max)
+ if (policy->cur < policy->max && target == policy->max)
this_dbs_info->rate_mult =
dbs_tuners_ins.sampling_down_factor;
- dbs_freq_increase(policy, policy->max);
+ dbs_freq_increase(policy, target);
return;
}
/* Check for frequency decrease */
+#if !defined(CONFIG_ARCH_EXYNOS4) && !defined(CONFIG_ARCH_EXYNOS5)
/* if we cannot reduce the frequency anymore, break out early */
if (policy->cur == policy->min)
return;
+#endif
/*
* The optimal frequency is the frequency that is the lowest that
@@ -563,7 +775,7 @@ static void do_dbs_timer(struct work_struct *work)
/* We want all CPUs to do sampling nearly on
* same jiffy
*/
- delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate
+ delay = usecs_to_jiffies(effective_sampling_rate()
* dbs_info->rate_mult);
if (num_online_cpus() > 1)
@@ -574,6 +786,23 @@ static void do_dbs_timer(struct work_struct *work)
dbs_info->freq_lo, CPUFREQ_RELATION_H);
delay = dbs_info->freq_lo_jiffies;
}
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+ if (dbs_info->flex_duration) {
+ struct cpufreq_policy *policy = dbs_info->cur_policy;
+
+ mutex_lock(&flex_mutex);
+ delay = usecs_to_jiffies(dbs_tuners_ins.flex_sampling_rate);
+
+ /* If it's already max, we don't need to iterate fast */
+ if (policy->cur >= policy->max)
+ dbs_info->flex_duration = 1;
+
+ if (--dbs_info->flex_duration < dbs_tuners_ins.flex_duration) {
+ dbs_tuners_ins.flex_duration = dbs_info->flex_duration;
+ }
+ mutex_unlock(&flex_mutex);
+ }
+#endif /* CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE */
schedule_delayed_work_on(cpu, &dbs_info->work, delay);
mutex_unlock(&dbs_info->timer_mutex);
}
@@ -581,18 +810,20 @@ static void do_dbs_timer(struct work_struct *work)
static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
{
/* We want all CPUs to do sampling nearly on same jiffy */
- int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ int delay = usecs_to_jiffies(effective_sampling_rate());
if (num_online_cpus() > 1)
delay -= jiffies % delay;
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
- schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay);
+ schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, 10 * delay);
+ dbs_info->activated = true;
}
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
+ dbs_info->activated = false;
cancel_delayed_work_sync(&dbs_info->work);
}
@@ -711,11 +942,40 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
return 0;
}
+/**
+ * qos_dvfs_lat_notify - PM QoS Notifier for DVFS_LATENCY QoS Request
+ * @nb notifier block struct
+ * @value QoS value
+ * @dummy
+ */
+static int qos_dvfs_lat_notify(struct notifier_block *nb, unsigned long value,
+ void *dummy)
+{
+ /*
+ * In the worst case, with a continuous up-treshold + e cpu load
+ * from up-threshold - e load, the ondemand governor will react
+ * sampling_rate * 2.
+ *
+ * Thus, based on the worst case scenario, we use value / 2;
+ */
+ dbs_tuners_ins.dvfs_lat_qos_wants = value / 2;
+
+ /* Update sampling rate */
+ update_sampling_rate(0);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block ondemand_qos_dvfs_lat_nb = {
+ .notifier_call = qos_dvfs_lat_notify,
+};
+
static int __init cpufreq_gov_dbs_init(void)
{
cputime64_t wall;
u64 idle_time;
int cpu = get_cpu();
+ int err = 0;
idle_time = get_cpu_idle_time_us(cpu, &wall);
put_cpu();
@@ -736,14 +996,241 @@ static int __init cpufreq_gov_dbs_init(void)
MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10);
}
- return cpufreq_register_governor(&cpufreq_gov_ondemand);
+ err = pm_qos_add_notifier(PM_QOS_DVFS_RESPONSE_LATENCY,
+ &ondemand_qos_dvfs_lat_nb);
+ if (err)
+ return err;
+
+ err = cpufreq_register_governor(&cpufreq_gov_ondemand);
+ if (err) {
+ pm_qos_remove_notifier(PM_QOS_DVFS_RESPONSE_LATENCY,
+ &ondemand_qos_dvfs_lat_nb);
+ }
+
+ return err;
}
static void __exit cpufreq_gov_dbs_exit(void)
{
+ pm_qos_remove_notifier(PM_QOS_DVFS_RESPONSE_LATENCY,
+ &ondemand_qos_dvfs_lat_nb);
+
cpufreq_unregister_governor(&cpufreq_gov_ondemand);
}
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+static unsigned int max_duration =
+ (CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE_MAX_DURATION);
+#define DEFAULT_DURATION (5)
+static unsigned int sysfs_duration = DEFAULT_DURATION;
+static bool flexrate_enabled = true;
+static unsigned int forced_rate;
+static unsigned int flexrate_num_effective;
+
+static int cpufreq_ondemand_flexrate_do(struct cpufreq_policy *policy,
+ bool now)
+{
+ unsigned int cpu = policy->cpu;
+ bool using_ondemand;
+ struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
+
+ WARN(!mutex_is_locked(&flex_mutex), "flex_mutex not locked\n");
+
+ dbs_info->flex_duration = dbs_tuners_ins.flex_duration;
+
+ if (now) {
+ flexrate_num_effective++;
+
+ mutex_lock(&dbs_mutex);
+ using_ondemand = dbs_enable && !strncmp(policy->governor->name, "ondemand", 8);
+ mutex_unlock(&dbs_mutex);
+
+ if (!using_ondemand)
+ return 0;
+
+ mutex_unlock(&flex_mutex);
+ mutex_lock(&dbs_info->timer_mutex);
+
+ /* Do It! */
+ cancel_delayed_work_sync(&dbs_info->work);
+ schedule_delayed_work_on(cpu, &dbs_info->work, 1);
+
+ mutex_unlock(&dbs_info->timer_mutex);
+ mutex_lock(&flex_mutex);
+ }
+
+ return 0;
+}
+
+int cpufreq_ondemand_flexrate_request(unsigned int rate_us,
+ unsigned int duration)
+{
+ int err = 0;
+
+ if (!flexrate_enabled)
+ return 0;
+
+ if (forced_rate)
+ rate_us = forced_rate;
+
+ mutex_lock(&flex_mutex);
+
+ /* Unnecessary requests are dropped */
+ if (rate_us >= dbs_tuners_ins.sampling_rate)
+ goto out;
+ if (rate_us >= dbs_tuners_ins.flex_sampling_rate &&
+ duration <= dbs_tuners_ins.flex_duration)
+ goto out;
+
+ duration = min(max_duration, duration);
+ if (rate_us > 0 && rate_us < min_sampling_rate)
+ rate_us = min_sampling_rate;
+
+ err = 1; /* Need update */
+
+ /* Cancel the active flexrate requests */
+ if (rate_us == 0 || duration == 0) {
+ dbs_tuners_ins.flex_duration = 0;
+ dbs_tuners_ins.flex_sampling_rate = 0;
+ goto out;
+ }
+
+ if (dbs_tuners_ins.flex_sampling_rate == 0 ||
+ dbs_tuners_ins.flex_sampling_rate > rate_us)
+ err = 2; /* Need to poll faster */
+
+ /* Set new flexrate per the request */
+ dbs_tuners_ins.flex_sampling_rate =
+ min(dbs_tuners_ins.flex_sampling_rate, rate_us);
+ dbs_tuners_ins.flex_duration =
+ max(dbs_tuners_ins.flex_duration, duration);
+out:
+ /* Apply new flexrate */
+ if (err > 0) {
+ bool now = (err == 2);
+ int cpu = 0;
+
+ /* TODO: For every CPU using ONDEMAND */
+ err = cpufreq_ondemand_flexrate_do(cpufreq_cpu_get(cpu), now);
+ }
+ mutex_unlock(&flex_mutex);
+ return err;
+}
+EXPORT_SYMBOL_GPL(cpufreq_ondemand_flexrate_request);
+
+static ssize_t store_flexrate_request(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int rate;
+ int ret;
+
+ ret = sscanf(buf, "%u", &rate);
+ if (ret != 1)
+ return -EINVAL;
+
+ ret = cpufreq_ondemand_flexrate_request(rate, sysfs_duration);
+ if (ret)
+ return ret;
+ return count;
+}
+
+static ssize_t show_flexrate_request(struct kobject *a, struct attribute *b,
+ char *buf)
+{
+ return sprintf(buf, "Flexrate decreases CPUFreq Ondemand governor's polling rate temporaily.\n"
+ "Usage Example:\n"
+ "# echo 8 > flexrate_duration\n"
+ "# echo 10000 > flexrate_request\n"
+ "With the second statement, Ondemand polls with 10ms(10000us) interval 8 times.\n"
+ "run \"echo flexrate_duration\" to see the currecnt duration setting.\n");
+}
+
+static ssize_t store_flexrate_duration(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int duration;
+ int ret;
+
+ /* mutex not needed for flexrate_sysfs_duration */
+ ret = sscanf(buf, "%u", &duration);
+ if (ret != 1)
+ return -EINVAL;
+
+ if (duration == 0)
+ duration = DEFAULT_DURATION;
+ if (duration > max_duration)
+ duration = max_duration;
+
+ sysfs_duration = duration;
+ return count;
+}
+
+static ssize_t show_flexrate_duration(struct kobject *a, struct attribute *b,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", sysfs_duration);
+}
+
+static ssize_t store_flexrate_enable(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ if (input > 0)
+ flexrate_enabled = true;
+ else
+ flexrate_enabled = false;
+
+ return count;
+}
+
+static ssize_t show_flexrate_enable(struct kobject *a, struct attribute *b,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!flexrate_enabled);
+}
+
+static ssize_t store_flexrate_forcerate(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int rate;
+ int ret;
+
+ ret = sscanf(buf, "%u", &rate);
+ if (ret != 1)
+ return -EINVAL;
+
+ forced_rate = rate;
+
+ pr_info("CAUTION: flexrate_forcerate is for debugging/benchmarking only.\n");
+ return count;
+}
+
+static ssize_t show_flexrate_forcerate(struct kobject *a, struct attribute *b,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", forced_rate);
+}
+
+static ssize_t show_flexrate_num_effective_usage(struct kobject *a,
+ struct attribute *b,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", flexrate_num_effective);
+}
+
+define_one_global_rw(flexrate_request);
+define_one_global_rw(flexrate_duration);
+define_one_global_rw(flexrate_enable);
+define_one_global_rw(flexrate_forcerate);
+define_one_global_ro(flexrate_num_effective_usage);
+#endif
+
MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
diff --git aosp-v3.0/drivers/crypto/Kconfig smdk4210/drivers/crypto/Kconfig
index e0b25de..a326e63 100644
--- aosp-v3.0/drivers/crypto/Kconfig
+++ smdk4210/drivers/crypto/Kconfig
@@ -292,4 +292,59 @@ config CRYPTO_DEV_S5P
Select this to offload Samsung S5PV210 or S5PC110 from AES
algorithms execution.
+config CRYPTO_S5P_DEV_ACE
+ tristate "Support for Samsung ACE (Advanced Crypto Engine)"
+ depends on ARCH_EXYNOS4 || ARCH_EXYNOS5 || ARCH_S5PV210
+ select S5P_DEV_ACE
+ select CRYPTO_ALGAPI
+ help
+ Use ACE for AES (ECB, CBC, CTR) and SHA1/SHA256.
+ Available in EXYNOS4/S5PV210/S5PC110 and newer CPUs.
+
+config ACE_BC
+ bool "Support for AES block cipher (ECB, CBC, CTR mode)"
+ depends on CRYPTO_S5P_DEV_ACE
+ select CRYPTO_AES
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_ECB
+ select CRYPTO_CTR
+ select CRYPTO_CBC
+ default y
+ help
+ Use ACE for ACE (ECB, CBC, CTR) for Samsung Hardware Crypto engine.
+
+config ACE_BC_ASYNC
+ bool "Support for AES async mode"
+ default y
+ depends on ACE_BC
+
+config ACE_BC_IRQMODE
+ bool "Support for AES IRQ mode"
+ default n
+ depends on ACE_BC_ASYNC
+
+config ACE_HASH_SHA1
+ bool "Support for SHA1 hash algorithm"
+ depends on CRYPTO_S5P_DEV_ACE
+ select CRYPTO_HASH
+ select CRYPTO_SHA1
+ default y
+ help
+ Use SHA1 hash algorithm for Samsung Hardware Crypto engine
+
+config ACE_HASH_SHA256
+ bool "Support for SHA256 hash algorithm"
+ depends on CRYPTO_S5P_DEV_ACE && !ARCH_S5PV210
+ select CRYPTO_HASH
+ select CRYPTO_SHA256
+ default y
+ help
+ Use SHA256 hash algorithm for Samsung Hardware Crypto engine
+
+config ACE_DEBUG
+ bool "Debug message for crypto driver"
+ depends on CRYPTO_S5P_DEV_ACE
+ help
+ This option allows you to check the debug print message for crypto driver.
+
endif # CRYPTO_HW
diff --git aosp-v3.0/drivers/crypto/Makefile smdk4210/drivers/crypto/Makefile
index 53ea501..4fe1e44 100644
--- aosp-v3.0/drivers/crypto/Makefile
+++ smdk4210/drivers/crypto/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
+obj-$(CONFIG_CRYPTO_S5P_DEV_ACE) += ace.o
diff --git aosp-v3.0/drivers/gpio/Kconfig smdk4210/drivers/gpio/Kconfig
index 2967002..c16e914 100644
--- aosp-v3.0/drivers/gpio/Kconfig
+++ smdk4210/drivers/gpio/Kconfig
@@ -88,7 +88,11 @@ config GPIO_IT8761E
config GPIO_EXYNOS4
def_bool y
- depends on CPU_EXYNOS4210
+ depends on ARCH_EXYNOS4
+
+config GPIO_EXYNOS5
+ def_bool y
+ depends on ARCH_EXYNOS5
config GPIO_PLAT_SAMSUNG
def_bool y
diff --git aosp-v3.0/drivers/gpio/Makefile smdk4210/drivers/gpio/Makefile
index b605f8e..f141bb5 100644
--- aosp-v3.0/drivers/gpio/Makefile
+++ smdk4210/drivers/gpio/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o
obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o
obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
+obj-$(CONFIG_GPIO_EXYNOS5) += gpio-exynos5.o
obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
diff --git aosp-v3.0/drivers/gpio/gpio-exynos4.c smdk4210/drivers/gpio/gpio-exynos4.c
index 9029835..01b827b 100644
--- aosp-v3.0/drivers/gpio/gpio-exynos4.c
+++ smdk4210/drivers/gpio/gpio-exynos4.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/gpiolib.c
+/* linux/drivers/gpio/gpio-exynos4.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -20,6 +20,7 @@
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
+#include <plat/cpu.h>
int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
unsigned int off, s3c_gpio_pull_t pull)
@@ -55,7 +56,7 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
};
/*
- * Following are the gpio banks in v310.
+ * Following are the gpio banks in exynos4.
*
* The 'config' member when left to NULL, is initialized to the default
* structure gpio_cfg in the init function below.
@@ -64,162 +65,176 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
* Note: The initialization of 'base' member of s3c_gpio_chip structure
* uses the above macro and depends on the banks being listed in order here.
*/
-static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
+static struct s3c_gpio_pm s3c_gpio_pm_nop = { NULL, NULL };
+
+static struct s3c_gpio_chip exynos4_gpio_common_4bit[] = {
{
+ .base = S5P_VA_GPIO1,
+ .eint_offset = 0x0,
+ .group = 0,
.chip = {
.base = EXYNOS4_GPA0(0),
.ngpio = EXYNOS4_GPIO_A0_NR,
.label = "GPA0",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x20),
+ .eint_offset = 0x4,
+ .group = 1,
.chip = {
.base = EXYNOS4_GPA1(0),
.ngpio = EXYNOS4_GPIO_A1_NR,
.label = "GPA1",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x40),
+ .eint_offset = 0x8,
+ .group = 2,
.chip = {
.base = EXYNOS4_GPB(0),
.ngpio = EXYNOS4_GPIO_B_NR,
.label = "GPB",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x60),
+ .eint_offset = 0xC,
+ .group = 3,
.chip = {
.base = EXYNOS4_GPC0(0),
.ngpio = EXYNOS4_GPIO_C0_NR,
.label = "GPC0",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x80),
+ .eint_offset = 0x10,
+ .group = 4,
.chip = {
.base = EXYNOS4_GPC1(0),
.ngpio = EXYNOS4_GPIO_C1_NR,
.label = "GPC1",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0xA0),
+ .eint_offset = 0x14,
+ .group = 5,
.chip = {
.base = EXYNOS4_GPD0(0),
.ngpio = EXYNOS4_GPIO_D0_NR,
.label = "GPD0",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0xC0),
+ .eint_offset = 0x18,
+ .group = 6,
.chip = {
.base = EXYNOS4_GPD1(0),
.ngpio = EXYNOS4_GPIO_D1_NR,
.label = "GPD1",
},
}, {
- .chip = {
- .base = EXYNOS4_GPE0(0),
- .ngpio = EXYNOS4_GPIO_E0_NR,
- .label = "GPE0",
- },
- }, {
- .chip = {
- .base = EXYNOS4_GPE1(0),
- .ngpio = EXYNOS4_GPIO_E1_NR,
- .label = "GPE1",
- },
- }, {
- .chip = {
- .base = EXYNOS4_GPE2(0),
- .ngpio = EXYNOS4_GPIO_E2_NR,
- .label = "GPE2",
- },
- }, {
- .chip = {
- .base = EXYNOS4_GPE3(0),
- .ngpio = EXYNOS4_GPIO_E3_NR,
- .label = "GPE3",
- },
- }, {
- .chip = {
- .base = EXYNOS4_GPE4(0),
- .ngpio = EXYNOS4_GPIO_E4_NR,
- .label = "GPE4",
- },
- }, {
+ .base = (S5P_VA_GPIO1 + 0x180),
+ .eint_offset = 0x30,
+ .group = 7,
.chip = {
.base = EXYNOS4_GPF0(0),
.ngpio = EXYNOS4_GPIO_F0_NR,
.label = "GPF0",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x1A0),
+ .eint_offset = 0x34,
+ .group = 8,
.chip = {
.base = EXYNOS4_GPF1(0),
.ngpio = EXYNOS4_GPIO_F1_NR,
.label = "GPF1",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x1C0),
+ .eint_offset = 0x38,
+ .group = 9,
.chip = {
.base = EXYNOS4_GPF2(0),
.ngpio = EXYNOS4_GPIO_F2_NR,
.label = "GPF2",
},
}, {
+ .base = (S5P_VA_GPIO1 + 0x1E0),
+ .eint_offset = 0x3C,
+ .group = 10,
.chip = {
.base = EXYNOS4_GPF3(0),
.ngpio = EXYNOS4_GPIO_F3_NR,
.label = "GPF3",
},
- },
-};
-
-static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
- {
- .chip = {
- .base = EXYNOS4_GPJ0(0),
- .ngpio = EXYNOS4_GPIO_J0_NR,
- .label = "GPJ0",
- },
- }, {
- .chip = {
- .base = EXYNOS4_GPJ1(0),
- .ngpio = EXYNOS4_GPIO_J1_NR,
- .label = "GPJ1",
- },
}, {
+ .base = (S5P_VA_GPIO2 + 0x40),
+ .eint_offset = 0x8,
+ .group = 16,
.chip = {
.base = EXYNOS4_GPK0(0),
.ngpio = EXYNOS4_GPIO_K0_NR,
.label = "GPK0",
},
+#ifdef CONFIG_MACH_MIDAS
+ .pm = &s3c_gpio_pm_nop,
+#endif
}, {
+ .base = (S5P_VA_GPIO2 + 0x60),
+ .eint_offset = 0xC,
+ .group = 17,
.chip = {
.base = EXYNOS4_GPK1(0),
.ngpio = EXYNOS4_GPIO_K1_NR,
.label = "GPK1",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x80),
+ .eint_offset = 0x10,
+ .group = 18,
.chip = {
.base = EXYNOS4_GPK2(0),
.ngpio = EXYNOS4_GPIO_K2_NR,
.label = "GPK2",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0xA0),
+ .eint_offset = 0x14,
+ .group = 19,
.chip = {
.base = EXYNOS4_GPK3(0),
.ngpio = EXYNOS4_GPIO_K3_NR,
.label = "GPK3",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0xC0),
+ .eint_offset = 0x18,
+ .group = 20,
.chip = {
.base = EXYNOS4_GPL0(0),
.ngpio = EXYNOS4_GPIO_L0_NR,
.label = "GPL0",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0xE0),
+ .eint_offset = 0x1C,
+ .group = 21,
.chip = {
.base = EXYNOS4_GPL1(0),
.ngpio = EXYNOS4_GPIO_L1_NR,
.label = "GPL1",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x100),
+ .eint_offset = 0x20,
+ .group = 22,
.chip = {
.base = EXYNOS4_GPL2(0),
.ngpio = EXYNOS4_GPIO_L2_NR,
.label = "GPL2",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x120),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY0(0),
@@ -227,6 +242,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY0",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x140),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY1(0),
@@ -234,6 +250,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY1",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x160),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY2(0),
@@ -241,6 +258,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY2",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x180),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY3(0),
@@ -248,6 +266,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY3",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x1A0),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY4(0),
@@ -255,6 +274,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY4",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x1C0),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY5(0),
@@ -262,6 +282,7 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPY5",
},
}, {
+ .base = (S5P_VA_GPIO2 + 0x1E0),
.config = &gpio_cfg_noint,
.chip = {
.base = EXYNOS4_GPY6(0),
@@ -308,76 +329,344 @@ static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
.label = "GPX3",
.to_irq = samsung_gpiolib_to_irq,
},
+ }, {
+ .base = S5P_VA_GPIO3,
+ .chip = {
+ .base = EXYNOS4_GPZ(0),
+ .ngpio = EXYNOS4_GPIO_Z_NR,
+ .label = "GPZ",
+ },
},
};
-static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
+static struct s3c_gpio_chip exynos4210_gpio_4bit[] = {
{
+ .base = (S5P_VA_GPIO1 + 0xE0),
+ .eint_offset = 0x1C,
+ .group = 11,
.chip = {
- .base = EXYNOS4_GPZ(0),
- .ngpio = EXYNOS4_GPIO_Z_NR,
- .label = "GPZ",
+ .base = EXYNOS4210_GPE0(0),
+ .ngpio = EXYNOS4210_GPIO_E0_NR,
+ .label = "GPE0",
+ },
+ }, {
+ .base = (S5P_VA_GPIO1 + 0x100),
+ .eint_offset = 0x20,
+ .group = 12,
+ .chip = {
+ .base = EXYNOS4210_GPE1(0),
+ .ngpio = EXYNOS4210_GPIO_E1_NR,
+ .label = "GPE1",
+ },
+ }, {
+ .base = (S5P_VA_GPIO1 + 0x120),
+ .eint_offset = 0x24,
+ .group = 13,
+ .chip = {
+ .base = EXYNOS4210_GPE2(0),
+ .ngpio = EXYNOS4210_GPIO_E2_NR,
+ .label = "GPE2",
+ },
+ }, {
+ .base = (S5P_VA_GPIO1 + 0x140),
+ .eint_offset = 0x28,
+ .group = 14,
+ .chip = {
+ .base = EXYNOS4210_GPE3(0),
+ .ngpio = EXYNOS4210_GPIO_E3_NR,
+ .label = "GPE3",
+ },
+ }, {
+ .base = (S5P_VA_GPIO1 + 0x160),
+ .eint_offset = 0x2C,
+ .group = 15,
+ .chip = {
+ .base = EXYNOS4210_GPE4(0),
+ .ngpio = EXYNOS4210_GPIO_E4_NR,
+ .label = "GPE4",
+ },
+ }, {
+ .base = S5P_VA_GPIO2,
+ .group = 23,
+ .eint_offset = 0x0,
+ .chip = {
+ .base = EXYNOS4210_GPJ0(0),
+ .ngpio = EXYNOS4210_GPIO_J0_NR,
+ .label = "GPJ0",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x20),
+ .eint_offset = 0x4,
+ .group = 24,
+ .chip = {
+ .base = EXYNOS4210_GPJ1(0),
+ .ngpio = EXYNOS4210_GPIO_J1_NR,
+ .label = "GPJ1",
},
},
};
+static struct s3c_gpio_chip exynos4212_gpio_4bit[] = {
+ {
+ .base = (S5P_VA_GPIO1 + 0x240),
+ .eint_offset = 0x40,
+ .group = 11,
+ .chip = {
+ .base = EXYNOS4212_GPJ0(0),
+ .ngpio = EXYNOS4212_GPIO_J0_NR,
+ .label = "GPJ0",
+ },
+ }, {
+ .base = (S5P_VA_GPIO1 + 0x260),
+ .eint_offset = 0x44,
+ .group = 12,
+ .chip = {
+ .base = EXYNOS4212_GPJ1(0),
+ .ngpio = EXYNOS4212_GPIO_J1_NR,
+ .label = "GPJ1",
+ }
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x260),
+ .eint_offset = 0x24,
+ .group = 23,
+ .chip = {
+ .base = EXYNOS4212_GPM0(0),
+ .ngpio = EXYNOS4212_GPIO_M0_NR,
+ .label = "GPM0",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x280),
+ .eint_offset = 0x28,
+ .group = 24,
+ .chip = {
+ .base = EXYNOS4212_GPM1(0),
+ .ngpio = EXYNOS4212_GPIO_M1_NR,
+ .label = "GPM1",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x2A0),
+ .eint_offset = 0x2C,
+ .group = 25,
+ .chip = {
+ .base = EXYNOS4212_GPM2(0),
+ .ngpio = EXYNOS4212_GPIO_M2_NR,
+ .label = "GPM2",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x2C0),
+ .eint_offset = 0x30,
+ .group = 26,
+ .chip = {
+ .base = EXYNOS4212_GPM3(0),
+ .ngpio = EXYNOS4212_GPIO_M3_NR,
+ .label = "GPM3",
+ },
+ }, {
+ .base = (S5P_VA_GPIO2 + 0x2E0),
+ .eint_offset = 0x34,
+ .group = 27,
+ .chip = {
+ .base = EXYNOS4212_GPM4(0),
+ .ngpio = EXYNOS4212_GPIO_M4_NR,
+ .label = "GPM4",
+ },
+ }, {
+ .base = S5P_VA_GPIO4,
+ .eint_offset = 0x00,
+ .group = 28,
+ .chip = {
+ .base = EXYNOS4212_GPV0(0),
+ .ngpio = EXYNOS4212_GPIO_V0_NR,
+ .label = "GPV0",
+ },
+ }, {
+ .base = (S5P_VA_GPIO4 + 0x20),
+ .eint_offset = 0x04,
+ .group = 29,
+ .chip = {
+ .base = EXYNOS4212_GPV1(0),
+ .ngpio = EXYNOS4212_GPIO_V1_NR,
+ .label = "GPV1",
+ },
+ }, {
+ .base = (S5P_VA_GPIO4 + 0x60),
+ .eint_offset = 0x08,
+ .group = 30,
+ .chip = {
+ .base = EXYNOS4212_GPV2(0),
+ .ngpio = EXYNOS4212_GPIO_V2_NR,
+ .label = "GPV2",
+ },
+ }, {
+ .base = (S5P_VA_GPIO4 + 0x80),
+ .eint_offset = 0x0C,
+ .group = 31,
+ .chip = {
+ .base = EXYNOS4212_GPV3(0),
+ .ngpio = EXYNOS4212_GPIO_V3_NR,
+ .label = "GPV3",
+ },
+ }, {
+ .base = (S5P_VA_GPIO4 + 0xC0),
+ .eint_offset = 0x10,
+ .group = 32,
+ .chip = {
+ .base = EXYNOS4212_GPV4(0),
+ .ngpio = EXYNOS4212_GPIO_V4_NR,
+ .label = "GPV4",
+ },
+ },
+};
+
+/* EXYNOS4 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 >= EXYNOS4_GPX0(0)) && (pin <= EXYNOS4_GPX3(7)))
+ 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 >= EXYNOS4_GPX0(0)) && (pin <= EXYNOS4_GPX3(7)))
+ 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 >= EXYNOS4_GPX0(0)) && (pin <= EXYNOS4_GPX3(7)))
+ 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;
+}
+
static __init int exynos4_gpiolib_init(void)
{
struct s3c_gpio_chip *chip;
int i;
- int group = 0;
int nr_chips;
- /* GPIO part 1 */
+ /* GPIO common part */
- chip = exynos4_gpio_part1_4bit;
- nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
+ chip = exynos4_gpio_common_4bit;
+ nr_chips = ARRAY_SIZE(exynos4_gpio_common_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL) {
+ if (chip->config == NULL)
chip->config = &gpio_cfg;
- /* Assign the GPIO interrupt group */
- chip->group = group++;
- }
if (chip->base == NULL)
- chip->base = S5P_VA_GPIO1 + (i) * 0x20;
+ pr_err("No allocation of base address for [common gpio]");
}
- samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
+ samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, nr_chips);
- /* GPIO part 2 */
+ /* Only 4210 GPIO part */
+ if (soc_is_exynos4210()) {
+ chip = exynos4210_gpio_4bit;
+ nr_chips = ARRAY_SIZE(exynos4210_gpio_4bit);
- chip = exynos4_gpio_part2_4bit;
- nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
-
- for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL) {
- chip->config = &gpio_cfg;
- /* Assign the GPIO interrupt group */
- chip->group = group++;
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL)
+ chip->config = &gpio_cfg;
+ if (chip->base == NULL)
+ pr_err("No allocation of base address [4210 gpio]");
}
- if (chip->base == NULL)
- chip->base = S5P_VA_GPIO2 + (i) * 0x20;
- }
-
- samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
-
- /* GPIO part 3 */
- chip = exynos4_gpio_part3_4bit;
- nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
+ samsung_gpiolib_add_4bit_chips(exynos4210_gpio_4bit, nr_chips);
+ } else {
+ /* Only 4212/4412 GPIO part */
+ chip = exynos4212_gpio_4bit;
+ nr_chips = ARRAY_SIZE(exynos4212_gpio_4bit);
- for (i = 0; i < nr_chips; i++, chip++) {
- if (chip->config == NULL) {
- chip->config = &gpio_cfg;
- /* Assign the GPIO interrupt group */
- chip->group = group++;
+ for (i = 0; i < nr_chips; i++, chip++) {
+ if (chip->config == NULL)
+ chip->config = &gpio_cfg;
+ if (chip->base == NULL)
+ pr_err("No allocation of base address [4212 gpio]");
}
- if (chip->base == NULL)
- chip->base = S5P_VA_GPIO3 + (i) * 0x20;
+
+ samsung_gpiolib_add_4bit_chips(exynos4212_gpio_4bit, nr_chips);
}
- samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
diff --git aosp-v3.0/drivers/gpio/gpio-plat-samsung.c smdk4210/drivers/gpio/gpio-plat-samsung.c
index ea37c04..29a6e4f 100644
--- aosp-v3.0/drivers/gpio/gpio-plat-samsung.c
+++ smdk4210/drivers/gpio/gpio-plat-samsung.c
@@ -49,12 +49,17 @@ static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
+ unsigned long flags;
unsigned long con;
+ s3c_gpio_lock(ourchip, flags);
+
con = __raw_readl(base + GPIOCON_OFF);
con &= ~(0xf << con_4bit_shift(offset));
__raw_writel(con, base + GPIOCON_OFF);
+ s3c_gpio_unlock(ourchip, flags);
+
gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
return 0;
@@ -65,9 +70,12 @@ static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
+ unsigned long flags;
unsigned long con;
unsigned long dat;
+ s3c_gpio_lock(ourchip, flags);
+
con = __raw_readl(base + GPIOCON_OFF);
con &= ~(0xf << con_4bit_shift(offset));
con |= 0x1 << con_4bit_shift(offset);
@@ -83,6 +91,8 @@ static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
__raw_writel(con, base + GPIOCON_OFF);
__raw_writel(dat, base + GPIODAT_OFF);
+ s3c_gpio_unlock(ourchip, flags);
+
gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
return 0;
@@ -115,6 +125,7 @@ static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
void __iomem *regcon = base;
+ unsigned long flags;
unsigned long con;
if (offset > 7)
@@ -122,10 +133,14 @@ static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
else
regcon -= 4;
+ s3c_gpio_lock(ourchip, flags);
+
con = __raw_readl(regcon);
con &= ~(0xf << con_4bit_shift(offset));
__raw_writel(con, regcon);
+ s3c_gpio_unlock(ourchip, flags);
+
gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
return 0;
@@ -137,6 +152,7 @@ static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
void __iomem *regcon = base;
+ unsigned long flags;
unsigned long con;
unsigned long dat;
unsigned con_offset = offset;
@@ -146,6 +162,8 @@ static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
else
regcon -= 4;
+ s3c_gpio_lock(ourchip, flags);
+
con = __raw_readl(regcon);
con &= ~(0xf << con_4bit_shift(con_offset));
con |= 0x1 << con_4bit_shift(con_offset);
@@ -161,6 +179,8 @@ static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
__raw_writel(con, regcon);
__raw_writel(dat, base + GPIODAT_OFF);
+ s3c_gpio_unlock(ourchip, flags);
+
gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
return 0;
@@ -170,14 +190,20 @@ void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = samsung_gpiolib_4bit_input;
chip->chip.direction_output = samsung_gpiolib_4bit_output;
- chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+ chip->pm = chip->pm ?: __gpio_pm(&s3c_gpio_pm_4bit);
}
void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = samsung_gpiolib_4bit2_input;
chip->chip.direction_output = samsung_gpiolib_4bit2_output;
- chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
+ chip->pm = chip->pm ?: __gpio_pm(&s3c_gpio_pm_4bit);
+}
+
+void __init samsung_gpiolib_add_4bit_no_pm(struct s3c_gpio_chip *chip)
+{
+ chip->chip.direction_input = samsung_gpiolib_4bit_input;
+ chip->chip.direction_output = samsung_gpiolib_4bit_output;
}
void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
@@ -189,6 +215,15 @@ void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
}
}
+void __init samsung_gpiolib_add_4bit_chips_no_pm(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ samsung_gpiolib_add_4bit_no_pm(chip);
+ s3c_gpiolib_add(chip);
+ }
+}
+
void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
int nr_chips)
{
diff --git aosp-v3.0/drivers/gpu/Makefile smdk4210/drivers/gpu/Makefile
index ca2d3b3..f9d0bac 100644
--- aosp-v3.0/drivers/gpu/Makefile
+++ smdk4210/drivers/gpu/Makefile
@@ -1 +1,6 @@
-obj-y += drm/ vga/ stub/ ion/
+ifeq ($(CONFIG_VITHAR_HWVER_R0P0),y)
+obj-y += drm/ vga/ stub/ ion/
+else
+obj-y += drm/ vga/ stub/ ion/
+endif
+
diff --git aosp-v3.0/drivers/gpu/drm/Kconfig smdk4210/drivers/gpu/drm/Kconfig
index b493663..9fc6d9b 100644
--- aosp-v3.0/drivers/gpu/drm/Kconfig
+++ smdk4210/drivers/gpu/drm/Kconfig
@@ -9,7 +9,7 @@ menuconfig DRM
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
select I2C
select I2C_ALGOBIT
- select SLOW_WORK
+ select DMA_SHARED_BUFFER
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
@@ -19,6 +19,11 @@ menuconfig DRM
details. You should also select and configure AGP
(/dev/agpgart) support if it is available for your platform.
+config DRM_USB
+ tristate
+ depends on DRM
+ select USB
+
config DRM_KMS_HELPER
tristate
depends on DRM
@@ -28,6 +33,18 @@ config DRM_KMS_HELPER
help
FB and CRTC helpers for KMS drivers.
+config DRM_LOAD_EDID_FIRMWARE
+ bool "Allow to specify an EDID data set instead of probing for it"
+ depends on DRM_KMS_HELPER
+ help
+ Say Y here, if you want to use EDID data to be loaded from the
+ /lib/firmware directory or one of the provided built-in
+ data sets. This may be necessary, if the graphics adapter or
+ monitor are unable to provide appropriate EDID data. Since this
+ feature is provided as a workaround for broken hardware, the
+ default case is N. Details and instructions how to build your own
+ EDID data are given in Documentation/EDID/HOWTO.txt.
+
config DRM_TTM
tristate
depends on DRM
@@ -96,6 +113,7 @@ config DRM_I915
select FB_CFB_IMAGEBLIT
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
+ select BACKLIGHT_LCD_SUPPORT if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select VIDEO_OUTPUT_CONTROL if ACPI
select INPUT if ACPI
@@ -158,3 +176,11 @@ config DRM_SAVAGE
help
Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
chipset. If M is selected the module will be called savage.
+
+source "drivers/gpu/drm/exynos/Kconfig"
+
+source "drivers/gpu/drm/vmwgfx/Kconfig"
+
+source "drivers/gpu/drm/gma500/Kconfig"
+
+source "drivers/gpu/drm/udl/Kconfig"
diff --git aosp-v3.0/drivers/gpu/drm/Makefile smdk4210/drivers/gpu/drm/Makefile
index 89cf05a..d11f4f3 100644
--- aosp-v3.0/drivers/gpu/drm/Makefile
+++ smdk4210/drivers/gpu/drm/Makefile
@@ -9,20 +9,24 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
- drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
+ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
drm_crtc.o drm_modes.o drm_edid.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \
- drm_trace_points.o drm_global.o drm_usb.o
+ drm_trace_points.o drm_global.o drm_prime.o drm_backlight.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
+drm-usb-y := drm_usb.o
+
drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o
+drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
CFLAGS_drm_trace_points.o := -I$(src)
obj-$(CONFIG_DRM) += drm.o
+obj-$(CONFIG_DRM_USB) += drm_usb.o
obj-$(CONFIG_DRM_TTM) += ttm/
obj-$(CONFIG_DRM_TDFX) += tdfx/
obj-$(CONFIG_DRM_R128) += r128/
@@ -35,4 +39,10 @@ obj-$(CONFIG_DRM_SAVAGE)+= savage/
obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
obj-$(CONFIG_DRM_VIA) +=via/
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
+ifeq ($(CONFIG_NAPLES_COMMON),y)
+else
+obj-$(CONFIG_DRM_EXYNOS) +=exynos/
+endif
+obj-$(CONFIG_DRM_GMA500) += gma500/
+obj-$(CONFIG_DRM_UDL) += udl/
obj-y += i2c/
diff --git aosp-v3.0/drivers/gpu/drm/drm_context.c smdk4210/drivers/gpu/drm/drm_context.c
index 6d440fb..325365f 100644
--- aosp-v3.0/drivers/gpu/drm/drm_context.c
+++ smdk4210/drivers/gpu/drm/drm_context.c
@@ -154,8 +154,6 @@ int drm_getsareactx(struct drm_device *dev, void *data,
return -EINVAL;
}
- mutex_unlock(&dev->struct_mutex);
-
request->handle = NULL;
list_for_each_entry(_entry, &dev->maplist, head) {
if (_entry->map == map) {
@@ -164,6 +162,9 @@ int drm_getsareactx(struct drm_device *dev, void *data,
break;
}
}
+
+ mutex_unlock(&dev->struct_mutex);
+
if (request->handle == NULL)
return -EINVAL;
diff --git aosp-v3.0/drivers/gpu/drm/drm_crtc.c smdk4210/drivers/gpu/drm/drm_crtc.c
index 1367ced..e8acc19 100644
--- aosp-v3.0/drivers/gpu/drm/drm_crtc.c
+++ smdk4210/drivers/gpu/drm/drm_crtc.c
@@ -35,11 +35,7 @@
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_edid.h"
-
-struct drm_prop_enum_list {
- int type;
- char *name;
-};
+#include "drm_fourcc.h"
/* Avoid boilerplate. I'm tired of typing. */
#define DRM_ENUM_NAME_FN(fnname, list) \
@@ -162,6 +158,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
{ DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
+ { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
};
static struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -170,6 +167,7 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] =
{ DRM_MODE_ENCODER_TMDS, "TMDS" },
{ DRM_MODE_ENCODER_LVDS, "LVDS" },
{ DRM_MODE_ENCODER_TVDAC, "TV" },
+ { DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
};
char *drm_get_encoder_name(struct drm_encoder *encoder)
@@ -294,9 +292,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
int ret;
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
- if (ret) {
+ if (ret)
return ret;
- }
fb->dev = dev;
fb->funcs = funcs;
@@ -321,6 +318,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
{
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
+ struct drm_plane *plane;
struct drm_mode_set set;
int ret;
@@ -337,6 +335,18 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
}
}
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+ if (plane->fb == fb) {
+ /* should turn off the crtc */
+ ret = plane->funcs->disable_plane(plane);
+ if (ret)
+ DRM_ERROR("failed to disable plane with busy fb\n");
+ /* disconnect the plane from the fb and crtc: */
+ plane->fb = NULL;
+ plane->crtc = NULL;
+ }
+ }
+
drm_mode_object_put(dev, &fb->base);
list_del(&fb->head);
dev->mode_config.num_fb--;
@@ -353,19 +363,33 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
* Caller must hold mode config lock.
*
* Inits a new object created as base part of an driver crtc object.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
*/
-void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs)
{
+ int ret;
+
crtc->dev = dev;
crtc->funcs = funcs;
mutex_lock(&dev->mode_config.mutex);
- drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+
+ ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
+ if (ret)
+ goto out;
+
+ crtc->base.properties = &crtc->properties;
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
dev->mode_config.num_crtc++;
+
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
}
EXPORT_SYMBOL(drm_crtc_init);
@@ -425,7 +449,7 @@ void drm_mode_remove(struct drm_connector *connector,
struct drm_display_mode *mode)
{
list_del(&mode->head);
- kfree(mode);
+ drm_mode_destroy(connector->dev, mode);
}
EXPORT_SYMBOL(drm_mode_remove);
@@ -437,21 +461,30 @@ EXPORT_SYMBOL(drm_mode_remove);
* @name: user visible name of the connector
*
* LOCKING:
- * Caller must hold @dev's mode_config lock.
+ * Takes mode config lock.
*
* Initialises a preallocated connector. Connectors should be
* subclassed as part of driver connector objects.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
*/
-void drm_connector_init(struct drm_device *dev,
- struct drm_connector *connector,
- const struct drm_connector_funcs *funcs,
- int connector_type)
+int drm_connector_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type)
{
+ int ret;
+
mutex_lock(&dev->mode_config.mutex);
+ ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
+ if (ret)
+ goto out;
+
+ connector->base.properties = &connector->properties;
connector->dev = dev;
connector->funcs = funcs;
- drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
connector->connector_type = connector_type;
connector->connector_type_id =
++drm_connector_enum_list[connector_type].count; /* TODO */
@@ -463,13 +496,18 @@ void drm_connector_init(struct drm_device *dev,
list_add_tail(&connector->head, &dev->mode_config.connector_list);
dev->mode_config.num_connector++;
- drm_connector_attach_property(connector,
- dev->mode_config.edid_property, 0);
+ if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
+ drm_connector_attach_property(connector,
+ dev->mode_config.edid_property,
+ 0);
drm_connector_attach_property(connector,
dev->mode_config.dpms_property, 0);
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
}
EXPORT_SYMBOL(drm_connector_init);
@@ -478,7 +516,7 @@ EXPORT_SYMBOL(drm_connector_init);
* @connector: connector to cleanup
*
* LOCKING:
- * Caller must hold @dev's mode_config lock.
+ * Takes mode config lock.
*
* Cleans up the connector but doesn't free the object.
*/
@@ -499,27 +537,46 @@ void drm_connector_cleanup(struct drm_connector *connector)
mutex_lock(&dev->mode_config.mutex);
drm_mode_object_put(dev, &connector->base);
list_del(&connector->head);
+ dev->mode_config.num_connector--;
mutex_unlock(&dev->mode_config.mutex);
}
EXPORT_SYMBOL(drm_connector_cleanup);
-void drm_encoder_init(struct drm_device *dev,
+void drm_connector_unplug_all(struct drm_device *dev)
+{
+ struct drm_connector *connector;
+
+ /* taking the mode config mutex ends up in a clash with sysfs */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ drm_sysfs_connector_remove(connector);
+
+}
+EXPORT_SYMBOL(drm_connector_unplug_all);
+
+int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder,
const struct drm_encoder_funcs *funcs,
int encoder_type)
{
+ int ret;
+
mutex_lock(&dev->mode_config.mutex);
- encoder->dev = dev;
+ ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
+ if (ret)
+ goto out;
- drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
+ encoder->dev = dev;
encoder->encoder_type = encoder_type;
encoder->funcs = funcs;
list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
dev->mode_config.num_encoder++;
+ out:
mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
}
EXPORT_SYMBOL(drm_encoder_init);
@@ -529,10 +586,75 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
mutex_lock(&dev->mode_config.mutex);
drm_mode_object_put(dev, &encoder->base);
list_del(&encoder->head);
+ dev->mode_config.num_encoder--;
mutex_unlock(&dev->mode_config.mutex);
}
EXPORT_SYMBOL(drm_encoder_cleanup);
+int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
+ unsigned long possible_crtcs,
+ const struct drm_plane_funcs *funcs,
+ const uint32_t *formats, uint32_t format_count,
+ bool priv)
+{
+ int ret;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
+ if (ret)
+ goto out;
+
+ plane->base.properties = &plane->properties;
+ plane->dev = dev;
+ plane->funcs = funcs;
+ plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
+ GFP_KERNEL);
+ if (!plane->format_types) {
+ DRM_DEBUG_KMS("out of memory when allocating plane\n");
+ drm_mode_object_put(dev, &plane->base);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
+ plane->format_count = format_count;
+ plane->possible_crtcs = possible_crtcs;
+
+ /* private planes are not exposed to userspace, but depending on
+ * display hardware, might be convenient to allow sharing programming
+ * for the scanout engine with the crtc implementation.
+ */
+ if (!priv) {
+ list_add_tail(&plane->head, &dev->mode_config.plane_list);
+ dev->mode_config.num_plane++;
+ } else {
+ INIT_LIST_HEAD(&plane->head);
+ }
+
+ out:
+ mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_plane_init);
+
+void drm_plane_cleanup(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+
+ mutex_lock(&dev->mode_config.mutex);
+ kfree(plane->format_types);
+ drm_mode_object_put(dev, &plane->base);
+ /* if not added to a list, it must be a private plane */
+ if (!list_empty(&plane->head)) {
+ list_del(&plane->head);
+ dev->mode_config.num_plane--;
+ }
+ mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_plane_cleanup);
+
/**
* drm_mode_create - create a new display mode
* @dev: DRM device
@@ -553,7 +675,11 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev)
if (!nmode)
return NULL;
- drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE);
+ if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
+ kfree(nmode);
+ return NULL;
+ }
+
return nmode;
}
EXPORT_SYMBOL(drm_mode_create);
@@ -570,6 +696,9 @@ EXPORT_SYMBOL(drm_mode_create);
*/
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
{
+ if (!mode)
+ return;
+
drm_mode_object_put(dev, &mode->base);
kfree(mode);
@@ -580,7 +709,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
{
struct drm_property *edid;
struct drm_property *dpms;
- int i;
/*
* Standard properties (apply to all connectors)
@@ -590,11 +718,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
"EDID", 0);
dev->mode_config.edid_property = edid;
- dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
- "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
- drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
- drm_dpms_enum_list[i].name);
+ dpms = drm_property_create_enum(dev, 0,
+ "DPMS", drm_dpms_enum_list,
+ ARRAY_SIZE(drm_dpms_enum_list));
dev->mode_config.dpms_property = dpms;
return 0;
@@ -610,30 +736,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
{
struct drm_property *dvi_i_selector;
struct drm_property *dvi_i_subconnector;
- int i;
if (dev->mode_config.dvi_i_select_subconnector_property)
return 0;
dvi_i_selector =
- drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ drm_property_create_enum(dev, 0,
"select subconnector",
+ drm_dvi_i_select_enum_list,
ARRAY_SIZE(drm_dvi_i_select_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
- drm_property_add_enum(dvi_i_selector, i,
- drm_dvi_i_select_enum_list[i].type,
- drm_dvi_i_select_enum_list[i].name);
dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
- dvi_i_subconnector =
- drm_property_create(dev, DRM_MODE_PROP_ENUM |
- DRM_MODE_PROP_IMMUTABLE,
+ dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"subconnector",
+ drm_dvi_i_subconnector_enum_list,
ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
- drm_property_add_enum(dvi_i_subconnector, i,
- drm_dvi_i_subconnector_enum_list[i].type,
- drm_dvi_i_subconnector_enum_list[i].name);
dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
return 0;
@@ -664,51 +781,33 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
/*
* Basic connector properties
*/
- tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ tv_selector = drm_property_create_enum(dev, 0,
"select subconnector",
+ drm_tv_select_enum_list,
ARRAY_SIZE(drm_tv_select_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
- drm_property_add_enum(tv_selector, i,
- drm_tv_select_enum_list[i].type,
- drm_tv_select_enum_list[i].name);
dev->mode_config.tv_select_subconnector_property = tv_selector;
tv_subconnector =
- drm_property_create(dev, DRM_MODE_PROP_ENUM |
- DRM_MODE_PROP_IMMUTABLE, "subconnector",
+ drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+ "subconnector",
+ drm_tv_subconnector_enum_list,
ARRAY_SIZE(drm_tv_subconnector_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
- drm_property_add_enum(tv_subconnector, i,
- drm_tv_subconnector_enum_list[i].type,
- drm_tv_subconnector_enum_list[i].name);
dev->mode_config.tv_subconnector_property = tv_subconnector;
/*
* Other, TV specific properties: margins & TV modes.
*/
dev->mode_config.tv_left_margin_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "left margin", 2);
- dev->mode_config.tv_left_margin_property->values[0] = 0;
- dev->mode_config.tv_left_margin_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "left margin", 0, 100);
dev->mode_config.tv_right_margin_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "right margin", 2);
- dev->mode_config.tv_right_margin_property->values[0] = 0;
- dev->mode_config.tv_right_margin_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "right margin", 0, 100);
dev->mode_config.tv_top_margin_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "top margin", 2);
- dev->mode_config.tv_top_margin_property->values[0] = 0;
- dev->mode_config.tv_top_margin_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "top margin", 0, 100);
dev->mode_config.tv_bottom_margin_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "bottom margin", 2);
- dev->mode_config.tv_bottom_margin_property->values[0] = 0;
- dev->mode_config.tv_bottom_margin_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "bottom margin", 0, 100);
dev->mode_config.tv_mode_property =
drm_property_create(dev, DRM_MODE_PROP_ENUM,
@@ -718,40 +817,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
i, modes[i]);
dev->mode_config.tv_brightness_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "brightness", 2);
- dev->mode_config.tv_brightness_property->values[0] = 0;
- dev->mode_config.tv_brightness_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "brightness", 0, 100);
dev->mode_config.tv_contrast_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "contrast", 2);
- dev->mode_config.tv_contrast_property->values[0] = 0;
- dev->mode_config.tv_contrast_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "contrast", 0, 100);
dev->mode_config.tv_flicker_reduction_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "flicker reduction", 2);
- dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
- dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
dev->mode_config.tv_overscan_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "overscan", 2);
- dev->mode_config.tv_overscan_property->values[0] = 0;
- dev->mode_config.tv_overscan_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "overscan", 0, 100);
dev->mode_config.tv_saturation_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "saturation", 2);
- dev->mode_config.tv_saturation_property->values[0] = 0;
- dev->mode_config.tv_saturation_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "saturation", 0, 100);
dev->mode_config.tv_hue_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "hue", 2);
- dev->mode_config.tv_hue_property->values[0] = 0;
- dev->mode_config.tv_hue_property->values[1] = 100;
+ drm_property_create_range(dev, 0, "hue", 0, 100);
return 0;
}
@@ -767,18 +848,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
{
struct drm_property *scaling_mode;
- int i;
if (dev->mode_config.scaling_mode_property)
return 0;
scaling_mode =
- drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
+ drm_property_create_enum(dev, 0, "scaling mode",
+ drm_scaling_mode_enum_list,
ARRAY_SIZE(drm_scaling_mode_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
- drm_property_add_enum(scaling_mode, i,
- drm_scaling_mode_enum_list[i].type,
- drm_scaling_mode_enum_list[i].name);
dev->mode_config.scaling_mode_property = scaling_mode;
@@ -796,18 +873,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
int drm_mode_create_dithering_property(struct drm_device *dev)
{
struct drm_property *dithering_mode;
- int i;
if (dev->mode_config.dithering_mode_property)
return 0;
dithering_mode =
- drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
+ drm_property_create_enum(dev, 0, "dithering",
+ drm_dithering_mode_enum_list,
ARRAY_SIZE(drm_dithering_mode_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
- drm_property_add_enum(dithering_mode, i,
- drm_dithering_mode_enum_list[i].type,
- drm_dithering_mode_enum_list[i].name);
dev->mode_config.dithering_mode_property = dithering_mode;
return 0;
@@ -824,20 +897,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
int drm_mode_create_dirty_info_property(struct drm_device *dev)
{
struct drm_property *dirty_info;
- int i;
if (dev->mode_config.dirty_info_property)
return 0;
dirty_info =
- drm_property_create(dev, DRM_MODE_PROP_ENUM |
- DRM_MODE_PROP_IMMUTABLE,
+ drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"dirty",
+ drm_dirty_info_enum_list,
ARRAY_SIZE(drm_dirty_info_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
- drm_property_add_enum(dirty_info, i,
- drm_dirty_info_enum_list[i].type,
- drm_dirty_info_enum_list[i].name);
dev->mode_config.dirty_info_property = dirty_info;
return 0;
@@ -864,6 +932,7 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.encoder_list);
INIT_LIST_HEAD(&dev->mode_config.property_list);
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
+ INIT_LIST_HEAD(&dev->mode_config.plane_list);
idr_init(&dev->mode_config.crtc_idr);
mutex_lock(&dev->mode_config.mutex);
@@ -920,6 +989,7 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
return 0;
}
+EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
/**
* drm_mode_config_cleanup - free up DRM mode_config info
@@ -940,6 +1010,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
+ struct drm_plane *plane, *plt;
list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list,
head) {
@@ -964,6 +1035,13 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc->funcs->destroy(crtc);
}
+ list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list,
+ head) {
+ plane->funcs->destroy(plane);
+ }
+
+ idr_remove_all(&dev->mode_config.crtc_idr);
+ idr_destroy(&dev->mode_config.crtc_idr);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
@@ -978,9 +1056,16 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
* Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
* the user.
*/
-void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
- struct drm_display_mode *in)
+static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
+ const struct drm_display_mode *in)
{
+ WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
+ in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
+ in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
+ in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
+ in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
+ "timing values too large for mode info\n");
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
@@ -1009,10 +1094,16 @@ void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out,
*
* Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
* the caller.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
*/
-void drm_crtc_convert_umode(struct drm_display_mode *out,
- struct drm_mode_modeinfo *in)
+static int drm_crtc_convert_umode(struct drm_display_mode *out,
+ const struct drm_mode_modeinfo *in)
{
+ if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
+ return -ERANGE;
+
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
@@ -1029,6 +1120,8 @@ void drm_crtc_convert_umode(struct drm_display_mode *out,
out->type = in->type;
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+
+ return 0;
}
/**
@@ -1227,7 +1320,7 @@ out:
* @arg: arg from ioctl
*
* LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
*
* Construct a CRTC configuration structure to return to the user.
*
@@ -1287,7 +1380,7 @@ out:
* @arg: arg from ioctl
*
* LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
*
* Construct a connector configuration structure to return to the user.
*
@@ -1332,11 +1425,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
}
connector = obj_to_connector(obj);
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] != 0) {
- props_count++;
- }
- }
+ props_count = connector->properties.count;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] != 0) {
@@ -1372,7 +1461,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
*/
if ((out_resp->count_modes >= mode_count) && mode_count) {
copied = 0;
- mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
+ mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;
list_for_each_entry(mode, &connector->modes, head) {
drm_crtc_convert_to_umode(&u_mode, mode);
if (copy_to_user(mode_ptr + copied,
@@ -1387,30 +1476,28 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
if ((out_resp->count_props >= props_count) && props_count) {
copied = 0;
- prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
- prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] != 0) {
- if (put_user(connector->property_ids[i],
- prop_ptr + copied)) {
- ret = -EFAULT;
- goto out;
- }
+ prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr);
+ prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr);
+ for (i = 0; i < connector->properties.count; i++) {
+ if (put_user(connector->properties.ids[i],
+ prop_ptr + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
- if (put_user(connector->property_values[i],
- prop_values + copied)) {
- ret = -EFAULT;
- goto out;
- }
- copied++;
+ if (put_user(connector->properties.values[i],
+ prop_values + copied)) {
+ ret = -EFAULT;
+ goto out;
}
+ copied++;
}
}
out_resp->count_props = props_count;
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
copied = 0;
- encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
+ encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] != 0) {
if (put_user(connector->encoder_ids[i],
@@ -1464,6 +1551,254 @@ out:
}
/**
+ * drm_mode_getplane_res - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Return an plane count and set of IDs.
+ */
+int drm_mode_getplane_res(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_get_plane_res *plane_resp = data;
+ struct drm_mode_config *config;
+ struct drm_plane *plane;
+ uint32_t __user *plane_ptr;
+ int copied = 0, ret = 0;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+ config = &dev->mode_config;
+
+ /*
+ * This ioctl is called twice, once to determine how much space is
+ * needed, and the 2nd time to fill it.
+ */
+ if (config->num_plane &&
+ (plane_resp->count_planes >= config->num_plane)) {
+ plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
+
+ list_for_each_entry(plane, &config->plane_list, head) {
+ if (put_user(plane->base.id, plane_ptr + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ }
+ plane_resp->count_planes = config->num_plane;
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+/**
+ * drm_mode_getplane - get plane info
+ * @dev: DRM device
+ * @data: ioctl data
+ * @file_priv: DRM file info
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Return plane info, including formats supported, gamma size, any
+ * current fb, etc.
+ */
+int drm_mode_getplane(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_get_plane *plane_resp = data;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ uint32_t __user *format_ptr;
+ int ret = 0;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+ obj = drm_mode_object_find(dev, plane_resp->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -ENOENT;
+ goto out;
+ }
+ plane = obj_to_plane(obj);
+
+ if (plane->crtc)
+ plane_resp->crtc_id = plane->crtc->base.id;
+ else
+ plane_resp->crtc_id = 0;
+
+ if (plane->fb)
+ plane_resp->fb_id = plane->fb->base.id;
+ else
+ plane_resp->fb_id = 0;
+
+ plane_resp->plane_id = plane->base.id;
+ plane_resp->possible_crtcs = plane->possible_crtcs;
+ plane_resp->gamma_size = plane->gamma_size;
+
+ /*
+ * This ioctl is called twice, once to determine how much space is
+ * needed, and the 2nd time to fill it.
+ */
+ if (plane->format_count &&
+ (plane_resp->count_format_types >= plane->format_count)) {
+ format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr;
+ if (copy_to_user(format_ptr,
+ plane->format_types,
+ sizeof(uint32_t) * plane->format_count)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+ plane_resp->count_format_types = plane->format_count;
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+/**
+ * drm_mode_setplane - set up or tear down an plane
+ * @dev: DRM device
+ * @data: ioctl data*
+ * @file_prive: DRM file info
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Set plane info, including placement, fb, scaling, and other factors.
+ * Or pass a NULL fb to disable.
+ */
+int drm_mode_setplane(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_set_plane *plane_req = data;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct drm_crtc *crtc;
+ struct drm_framebuffer *fb;
+ int ret = 0;
+ unsigned int fb_width, fb_height;
+ int i;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ /*
+ * First, find the plane, crtc, and fb objects. If not available,
+ * we don't bother to call the driver.
+ */
+ obj = drm_mode_object_find(dev, plane_req->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ DRM_DEBUG_KMS("Unknown plane ID %d\n",
+ plane_req->plane_id);
+ ret = -ENOENT;
+ goto out;
+ }
+ plane = obj_to_plane(obj);
+
+ /* No fb means shut it down */
+ if (!plane_req->fb_id) {
+ plane->funcs->disable_plane(plane);
+ plane->crtc = NULL;
+ plane->fb = NULL;
+ goto out;
+ }
+
+ obj = drm_mode_object_find(dev, plane_req->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!obj) {
+ DRM_DEBUG_KMS("Unknown crtc ID %d\n",
+ plane_req->crtc_id);
+ ret = -ENOENT;
+ goto out;
+ }
+ crtc = obj_to_crtc(obj);
+
+ obj = drm_mode_object_find(dev, plane_req->fb_id,
+ DRM_MODE_OBJECT_FB);
+ if (!obj) {
+ DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
+ plane_req->fb_id);
+ ret = -ENOENT;
+ goto out;
+ }
+ fb = obj_to_fb(obj);
+
+ /* Check whether this plane supports the fb pixel format. */
+ for (i = 0; i < plane->format_count; i++)
+ if (fb->pixel_format == plane->format_types[i])
+ break;
+ if (i == plane->format_count) {
+ DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ fb_width = fb->width << 16;
+ fb_height = fb->height << 16;
+
+ /* Make sure source coordinates are inside the fb. */
+ if (plane_req->src_w > fb_width ||
+ plane_req->src_x > fb_width - plane_req->src_w ||
+ plane_req->src_h > fb_height ||
+ plane_req->src_y > fb_height - plane_req->src_h) {
+ DRM_DEBUG_KMS("Invalid source coordinates "
+ "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
+ plane_req->src_w >> 16,
+ ((plane_req->src_w & 0xffff) * 15625) >> 10,
+ plane_req->src_h >> 16,
+ ((plane_req->src_h & 0xffff) * 15625) >> 10,
+ plane_req->src_x >> 16,
+ ((plane_req->src_x & 0xffff) * 15625) >> 10,
+ plane_req->src_y >> 16,
+ ((plane_req->src_y & 0xffff) * 15625) >> 10);
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ /* Give drivers some help against integer overflows */
+ if (plane_req->crtc_w > INT_MAX ||
+ plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
+ plane_req->crtc_h > INT_MAX ||
+ plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
+ DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
+ plane_req->crtc_w, plane_req->crtc_h,
+ plane_req->crtc_x, plane_req->crtc_y);
+ ret = -ERANGE;
+ goto out;
+ }
+
+ ret = plane->funcs->update_plane(plane, crtc, fb,
+ plane_req->crtc_x, plane_req->crtc_y,
+ plane_req->crtc_w, plane_req->crtc_h,
+ plane_req->src_x, plane_req->src_y,
+ plane_req->src_w, plane_req->src_h);
+ if (!ret) {
+ plane->crtc = crtc;
+ plane->fb = fb;
+ }
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+
+ return ret;
+}
+
+/**
* drm_mode_setcrtc - set CRTC configuration
* @inode: inode from the ioctl
* @filp: file * from the ioctl
@@ -1471,7 +1806,7 @@ out:
* @arg: arg from ioctl
*
* LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
*
* Build a new CRTC configuration based on user request.
*
@@ -1486,7 +1821,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_mode_config *config = &dev->mode_config;
struct drm_mode_crtc *crtc_req = data;
struct drm_mode_object *obj;
- struct drm_crtc *crtc, *crtcfb;
+ struct drm_crtc *crtc;
struct drm_connector **connector_set = NULL, *connector;
struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode = NULL;
@@ -1498,6 +1833,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
+ /* For some reason crtc x/y offsets are signed internally. */
+ if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
+ return -ERANGE;
+
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
DRM_MODE_OBJECT_CRTC);
@@ -1513,14 +1852,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
- list_for_each_entry(crtcfb,
- &dev->mode_config.crtc_list, head) {
- if (crtcfb == crtc) {
- DRM_DEBUG_KMS("Using current fb for "
- "setmode\n");
- fb = crtc->fb;
- }
+ if (!crtc->fb) {
+ DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
+ ret = -EINVAL;
+ goto out;
}
+ fb = crtc->fb;
} else {
obj = drm_mode_object_find(dev, crtc_req->fb_id,
DRM_MODE_OBJECT_FB);
@@ -1534,11 +1871,33 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}
mode = drm_mode_create(dev);
- drm_crtc_convert_umode(mode, &crtc_req->mode);
- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- }
+ if (!mode) {
+ ret = -ENOMEM;
+ goto out;
+ }
- if (crtc_req->count_connectors == 0 && mode) {
+ ret = drm_crtc_convert_umode(mode, &crtc_req->mode);
+ if (ret) {
+ DRM_DEBUG_KMS("Invalid mode\n");
+ goto out;
+ }
+
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+
+ if (mode->hdisplay > fb->width ||
+ mode->vdisplay > fb->height ||
+ crtc_req->x > fb->width - mode->hdisplay ||
+ crtc_req->y > fb->height - mode->vdisplay) {
+ DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb size %ux%u.\n",
+ mode->hdisplay, mode->vdisplay,
+ crtc_req->x, crtc_req->y,
+ fb->width, fb->height);
+ ret = -ENOSPC;
+ goto out;
+ }
+ }
+
+ if (crtc_req->count_connectors == 0 && mode) {
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
@@ -1569,7 +1928,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
}
for (i = 0; i < crtc_req->count_connectors; i++) {
- set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
+ set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
if (get_user(out_id, &set_connectors_ptr[i])) {
ret = -EFAULT;
goto out;
@@ -1603,6 +1962,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
out:
kfree(connector_set);
+ drm_mode_destroy(dev, mode);
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
@@ -1618,10 +1978,8 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- if (!req->flags) {
- DRM_ERROR("no operation set\n");
+ if (!req->flags)
return -EINVAL;
- }
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
@@ -1634,7 +1992,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (req->flags & DRM_MODE_CURSOR_BO) {
if (!crtc->funcs->cursor_set) {
- DRM_ERROR("crtc does not support cursor\n");
ret = -ENXIO;
goto out;
}
@@ -1647,7 +2004,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (crtc->funcs->cursor_move) {
ret = crtc->funcs->cursor_move(crtc, req->x, req->y);
} else {
- DRM_ERROR("crtc does not support cursor\n");
ret = -EFAULT;
goto out;
}
@@ -1657,6 +2013,42 @@ out:
return ret;
}
+/* Original addfb only supported RGB formats, so figure out which one */
+uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
+{
+ uint32_t fmt;
+
+ switch (bpp) {
+ case 8:
+ fmt = DRM_FORMAT_RGB332;
+ break;
+ case 16:
+ if (depth == 15)
+ fmt = DRM_FORMAT_XRGB1555;
+ else
+ fmt = DRM_FORMAT_RGB565;
+ break;
+ case 24:
+ fmt = DRM_FORMAT_RGB888;
+ break;
+ case 32:
+ if (depth == 24)
+ fmt = DRM_FORMAT_XRGB8888;
+ else if (depth == 30)
+ fmt = DRM_FORMAT_XRGB2101010;
+ else
+ fmt = DRM_FORMAT_ARGB8888;
+ break;
+ default:
+ DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n");
+ fmt = DRM_FORMAT_XRGB8888;
+ break;
+ }
+
+ return fmt;
+}
+EXPORT_SYMBOL(drm_mode_legacy_fb_format);
+
/**
* drm_mode_addfb - add an FB to the graphics configuration
* @inode: inode from the ioctl
@@ -1677,7 +2069,143 @@ out:
int drm_mode_addfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_fb_cmd *r = data;
+ struct drm_mode_fb_cmd *or = data;
+ struct drm_mode_fb_cmd2 r = {};
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_framebuffer *fb;
+ int ret = 0;
+
+ /* Use new struct with format internally */
+ r.fb_id = or->fb_id;
+ r.width = or->width;
+ r.height = or->height;
+ r.pitches[0] = or->pitch;
+ r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
+ r.handles[0] = or->handle;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ if ((config->min_width > r.width) || (r.width > config->max_width))
+ return -EINVAL;
+
+ if ((config->min_height > r.height) || (r.height > config->max_height))
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ /* TODO check buffer is sufficiently large */
+ /* TODO setup destructor callback */
+
+ fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
+ if (IS_ERR(fb)) {
+ DRM_ERROR("could not create framebuffer\n");
+ ret = PTR_ERR(fb);
+ goto out;
+ }
+
+ or->fb_id = fb->base.id;
+ list_add(&fb->filp_head, &file_priv->fbs);
+ DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+static int format_check(struct drm_mode_fb_cmd2 *r)
+{
+ uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN;
+
+ switch (format) {
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_RGB332:
+ case DRM_FORMAT_BGR233:
+ case DRM_FORMAT_XRGB4444:
+ case DRM_FORMAT_XBGR4444:
+ case DRM_FORMAT_RGBX4444:
+ case DRM_FORMAT_BGRX4444:
+ case DRM_FORMAT_ARGB4444:
+ case DRM_FORMAT_ABGR4444:
+ case DRM_FORMAT_RGBA4444:
+ case DRM_FORMAT_BGRA4444:
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XBGR1555:
+ case DRM_FORMAT_RGBX5551:
+ case DRM_FORMAT_BGRX5551:
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_RGBA5551:
+ case DRM_FORMAT_BGRA5551:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_BGR888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_BGRX1010102:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_BGRA1010102:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_AYUV:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ case DRM_FORMAT_NV12M:
+ case DRM_FORMAT_NV12MT:
+ case DRM_FORMAT_YUV410:
+ case DRM_FORMAT_YVU410:
+ case DRM_FORMAT_YUV411:
+ case DRM_FORMAT_YVU411:
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_YUV422:
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YVU444:
+ case DRM_FORMAT_YUV420M:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * drm_mode_addfb2 - add an FB to the graphics configuration
+ * @inode: inode from the ioctl
+ * @filp: file * from the ioctl
+ * @cmd: cmd from ioctl
+ * @arg: arg from ioctl
+ *
+ * LOCKING:
+ * Takes mode config lock.
+ *
+ * Add a new FB to the specified CRTC, given a user request with format.
+ *
+ * Called by the user via ioctl.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_addfb2(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_fb_cmd2 *r = data;
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
int ret = 0;
@@ -1686,18 +2214,23 @@ int drm_mode_addfb(struct drm_device *dev,
return -EINVAL;
if ((config->min_width > r->width) || (r->width > config->max_width)) {
- DRM_ERROR("mode new framebuffer width not within limits\n");
+ DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n",
+ r->width, config->min_width, config->max_width);
return -EINVAL;
}
if ((config->min_height > r->height) || (r->height > config->max_height)) {
- DRM_ERROR("mode new framebuffer height not within limits\n");
+ DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n",
+ r->height, config->min_height, config->max_height);
return -EINVAL;
}
- mutex_lock(&dev->mode_config.mutex);
+ ret = format_check(r);
+ if (ret) {
+ DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format);
+ return ret;
+ }
- /* TODO check buffer is sufficiently large */
- /* TODO setup destructor callback */
+ mutex_lock(&dev->mode_config.mutex);
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) {
@@ -1749,7 +2282,6 @@ int drm_mode_rmfb(struct drm_device *dev,
obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
/* TODO check that we really get a framebuffer back. */
if (!obj) {
- DRM_ERROR("mode invalid framebuffer id\n");
ret = -EINVAL;
goto out;
}
@@ -1760,7 +2292,6 @@ int drm_mode_rmfb(struct drm_device *dev,
found = 1;
if (!found) {
- DRM_ERROR("tried to remove a fb that we didn't own\n");
ret = -EINVAL;
goto out;
}
@@ -1784,7 +2315,7 @@ out:
* @arg: arg from ioctl
*
* LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
*
* Lookup the FB given its ID and return info about it.
*
@@ -1807,7 +2338,6 @@ int drm_mode_getfb(struct drm_device *dev,
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
- DRM_ERROR("invalid framebuffer id\n");
ret = -EINVAL;
goto out;
}
@@ -1817,7 +2347,7 @@ int drm_mode_getfb(struct drm_device *dev,
r->width = fb->width;
r->depth = fb->depth;
r->bpp = fb->bits_per_pixel;
- r->pitch = fb->pitch;
+ r->pitch = fb->pitches[0];
fb->funcs->create_handle(fb, file_priv, &r->handle);
out:
@@ -1843,14 +2373,13 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
mutex_lock(&dev->mode_config.mutex);
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
- DRM_ERROR("invalid framebuffer id\n");
ret = -EINVAL;
goto out_err1;
}
fb = obj_to_fb(obj);
num_clips = r->num_clips;
- clips_ptr = (struct drm_clip_rect *)(unsigned long)r->clips_ptr;
+ clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr;
if (!num_clips != !clips_ptr) {
ret = -EINVAL;
@@ -1935,38 +2464,48 @@ void drm_fb_release(struct drm_file *priv)
*
* Add @mode to @connector's user mode list.
*/
-static int drm_mode_attachmode(struct drm_device *dev,
- struct drm_connector *connector,
- struct drm_display_mode *mode)
+static void drm_mode_attachmode(struct drm_device *dev,
+ struct drm_connector *connector,
+ struct drm_display_mode *mode)
{
- int ret = 0;
-
list_add_tail(&mode->head, &connector->user_modes);
- return ret;
}
int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
- struct drm_display_mode *mode)
+ const struct drm_display_mode *mode)
{
struct drm_connector *connector;
int ret = 0;
- struct drm_display_mode *dup_mode;
- int need_dup = 0;
+ struct drm_display_mode *dup_mode, *next;
+ LIST_HEAD(list);
+
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (!connector->encoder)
- break;
+ continue;
if (connector->encoder->crtc == crtc) {
- if (need_dup)
- dup_mode = drm_mode_duplicate(dev, mode);
- else
- dup_mode = mode;
- ret = drm_mode_attachmode(dev, connector, dup_mode);
- if (ret)
- return ret;
- need_dup = 1;
+ dup_mode = drm_mode_duplicate(dev, mode);
+ if (!dup_mode) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ list_add_tail(&dup_mode->head, &list);
}
}
- return 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ continue;
+ if (connector->encoder->crtc == crtc)
+ list_move_tail(list.next, &connector->user_modes);
+ }
+
+ WARN_ON(!list_empty(&list));
+
+ out:
+ list_for_each_entry_safe(dup_mode, next, &list, head)
+ drm_mode_destroy(dev, dup_mode);
+
+ return ret;
}
EXPORT_SYMBOL(drm_mode_attachmode_crtc);
@@ -2045,9 +2584,14 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
goto out;
}
- drm_crtc_convert_umode(mode, umode);
+ ret = drm_crtc_convert_umode(mode, umode);
+ if (ret) {
+ DRM_DEBUG_KMS("Invalid mode\n");
+ drm_mode_destroy(dev, mode);
+ goto out;
+ }
- ret = drm_mode_attachmode(dev, connector, mode);
+ drm_mode_attachmode(dev, connector, mode);
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -2088,7 +2632,12 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
}
connector = obj_to_connector(obj);
- drm_crtc_convert_umode(&mode, umode);
+ ret = drm_crtc_convert_umode(&mode, umode);
+ if (ret) {
+ DRM_DEBUG_KMS("Invalid mode\n");
+ goto out;
+ }
+
ret = drm_mode_detachmode(dev, connector, &mode);
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -2099,6 +2648,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
const char *name, int num_values)
{
struct drm_property *property = NULL;
+ int ret;
property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
if (!property)
@@ -2110,28 +2660,116 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
goto fail;
}
- drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
+ ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
+ if (ret)
+ goto fail;
+
property->flags = flags;
property->num_values = num_values;
INIT_LIST_HEAD(&property->enum_blob_list);
- if (name)
+ if (name) {
strncpy(property->name, name, DRM_PROP_NAME_LEN);
+ property->name[DRM_PROP_NAME_LEN-1] = '\0';
+ }
list_add_tail(&property->head, &dev->mode_config.property_list);
return property;
fail:
+ kfree(property->values);
kfree(property);
return NULL;
}
EXPORT_SYMBOL(drm_property_create);
+struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
+ const char *name,
+ const struct drm_prop_enum_list *props,
+ int num_values)
+{
+ struct drm_property *property;
+ int i, ret;
+
+ flags |= DRM_MODE_PROP_ENUM;
+
+ property = drm_property_create(dev, flags, name, num_values);
+ if (!property)
+ return NULL;
+
+ for (i = 0; i < num_values; i++) {
+ ret = drm_property_add_enum(property, i,
+ props[i].type,
+ props[i].name);
+ if (ret) {
+ drm_property_destroy(dev, property);
+ return NULL;
+ }
+ }
+
+ return property;
+}
+EXPORT_SYMBOL(drm_property_create_enum);
+
+struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
+ int flags, const char *name,
+ const struct drm_prop_enum_list *props,
+ int num_values)
+{
+ struct drm_property *property;
+ int i, ret;
+
+ flags |= DRM_MODE_PROP_BITMASK;
+
+ property = drm_property_create(dev, flags, name, num_values);
+ if (!property)
+ return NULL;
+
+ for (i = 0; i < num_values; i++) {
+ ret = drm_property_add_enum(property, i,
+ props[i].type,
+ props[i].name);
+ if (ret) {
+ drm_property_destroy(dev, property);
+ return NULL;
+ }
+ }
+
+ return property;
+}
+EXPORT_SYMBOL(drm_property_create_bitmask);
+
+struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
+ const char *name,
+ uint64_t min, uint64_t max)
+{
+ struct drm_property *property;
+
+ flags |= DRM_MODE_PROP_RANGE;
+
+ property = drm_property_create(dev, flags, name, 2);
+ if (!property)
+ return NULL;
+
+ property->values[0] = min;
+ property->values[1] = max;
+
+ return property;
+}
+EXPORT_SYMBOL(drm_property_create_range);
+
int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name)
{
struct drm_property_enum *prop_enum;
- if (!(property->flags & DRM_MODE_PROP_ENUM))
+ if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)))
+ return -EINVAL;
+
+ /*
+ * Bitmask enum properties have the additional constraint of values
+ * from 0 to 63
+ */
+ if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63))
return -EINVAL;
if (!list_empty(&property->enum_blob_list)) {
@@ -2175,60 +2813,78 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
}
EXPORT_SYMBOL(drm_property_destroy);
-int drm_connector_attach_property(struct drm_connector *connector,
+void drm_connector_attach_property(struct drm_connector *connector,
struct drm_property *property, uint64_t init_val)
{
- int i;
-
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] == 0) {
- connector->property_ids[i] = property->base.id;
- connector->property_values[i] = init_val;
- break;
- }
- }
-
- if (i == DRM_CONNECTOR_MAX_PROPERTY)
- return -EINVAL;
- return 0;
+ drm_object_attach_property(&connector->base, property, init_val);
}
EXPORT_SYMBOL(drm_connector_attach_property);
int drm_connector_property_set_value(struct drm_connector *connector,
struct drm_property *property, uint64_t value)
{
+ return drm_object_property_set_value(&connector->base, property, value);
+}
+EXPORT_SYMBOL(drm_connector_property_set_value);
+
+int drm_connector_property_get_value(struct drm_connector *connector,
+ struct drm_property *property, uint64_t *val)
+{
+ return drm_object_property_get_value(&connector->base, property, val);
+}
+EXPORT_SYMBOL(drm_connector_property_get_value);
+
+void drm_object_attach_property(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t init_val)
+{
+ int count = obj->properties->count;
+
+ if (count == DRM_OBJECT_MAX_PROPERTY) {
+ WARN(1, "Failed to attach object property (type: 0x%x). Please "
+ "increase DRM_OBJECT_MAX_PROPERTY by 1 for each time "
+ "you see this message on the same object type.\n",
+ obj->type);
+ return;
+ }
+
+ obj->properties->ids[count] = property->base.id;
+ obj->properties->values[count] = init_val;
+ obj->properties->count++;
+}
+EXPORT_SYMBOL(drm_object_attach_property);
+
+int drm_object_property_set_value(struct drm_mode_object *obj,
+ struct drm_property *property, uint64_t val)
+{
int i;
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] == property->base.id) {
- connector->property_values[i] = value;
- break;
+ for (i = 0; i < obj->properties->count; i++) {
+ if (obj->properties->ids[i] == property->base.id) {
+ obj->properties->values[i] = val;
+ return 0;
}
}
- if (i == DRM_CONNECTOR_MAX_PROPERTY)
- return -EINVAL;
- return 0;
+ return -EINVAL;
}
-EXPORT_SYMBOL(drm_connector_property_set_value);
+EXPORT_SYMBOL(drm_object_property_set_value);
-int drm_connector_property_get_value(struct drm_connector *connector,
+int drm_object_property_get_value(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val)
{
int i;
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] == property->base.id) {
- *val = connector->property_values[i];
- break;
+ for (i = 0; i < obj->properties->count; i++) {
+ if (obj->properties->ids[i] == property->base.id) {
+ *val = obj->properties->values[i];
+ return 0;
}
}
- if (i == DRM_CONNECTOR_MAX_PROPERTY)
- return -EINVAL;
- return 0;
+ return -EINVAL;
}
-EXPORT_SYMBOL(drm_connector_property_get_value);
+EXPORT_SYMBOL(drm_object_property_get_value);
int drm_mode_getproperty_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
@@ -2244,7 +2900,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
struct drm_property_enum *prop_enum;
struct drm_mode_property_enum __user *enum_ptr;
struct drm_property_blob *prop_blob;
- uint32_t *blob_id_ptr;
+ uint32_t __user *blob_id_ptr;
uint64_t __user *values_ptr;
uint32_t __user *blob_length_ptr;
@@ -2259,7 +2915,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
}
property = obj_to_property(obj);
- if (property->flags & DRM_MODE_PROP_ENUM) {
+ if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
list_for_each_entry(prop_enum, &property->enum_blob_list, head)
enum_count++;
} else if (property->flags & DRM_MODE_PROP_BLOB) {
@@ -2274,7 +2930,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
out_resp->flags = property->flags;
if ((out_resp->count_values >= value_count) && value_count) {
- values_ptr = (uint64_t *)(unsigned long)out_resp->values_ptr;
+ values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr;
for (i = 0; i < value_count; i++) {
if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) {
ret = -EFAULT;
@@ -2284,10 +2940,10 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
}
out_resp->count_values = value_count;
- if (property->flags & DRM_MODE_PROP_ENUM) {
+ if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) {
if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
copied = 0;
- enum_ptr = (struct drm_mode_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
+ enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
@@ -2309,8 +2965,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
if (property->flags & DRM_MODE_PROP_BLOB) {
if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
copied = 0;
- blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
- blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
+ blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
+ blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
@@ -2337,6 +2993,7 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev
void *data)
{
struct drm_property_blob *blob;
+ int ret;
if (!length || !data)
return NULL;
@@ -2345,13 +3002,16 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev
if (!blob)
return NULL;
- blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
+ ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
+ if (ret) {
+ kfree(blob);
+ return NULL;
+ }
+
blob->length = length;
memcpy(blob->data, data, length);
- drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
-
list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
return blob;
}
@@ -2371,7 +3031,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
struct drm_mode_get_blob *out_resp = data;
struct drm_property_blob *blob;
int ret = 0;
- void *blob_ptr;
+ void __user *blob_ptr;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
@@ -2385,7 +3045,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
blob = obj_to_blob(obj);
if (out_resp->length == blob->length) {
- blob_ptr = (void *)(unsigned long)out_resp->data;
+ blob_ptr = (void __user *)(unsigned long)out_resp->data;
if (copy_to_user(blob_ptr, blob->data, blob->length)){
ret = -EFAULT;
goto done;
@@ -2426,75 +3086,202 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
+static bool drm_property_change_is_valid(struct drm_property *property,
+ __u64 value)
+{
+ if (property->flags & DRM_MODE_PROP_IMMUTABLE)
+ return false;
+ if (property->flags & DRM_MODE_PROP_RANGE) {
+ if (value < property->values[0] || value > property->values[1])
+ return false;
+ return true;
+ } else if (property->flags & DRM_MODE_PROP_BITMASK) {
+ int i;
+ __u64 valid_mask = 0;
+ for (i = 0; i < property->num_values; i++)
+ valid_mask |= (1ULL << property->values[i]);
+ return !(value & ~valid_mask);
+ } else {
+ int i;
+ for (i = 0; i < property->num_values; i++)
+ if (property->values[i] == value)
+ return true;
+ return false;
+ }
+}
+
int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_connector_set_property *out_resp = data;
- struct drm_mode_object *obj;
- struct drm_property *property;
- struct drm_connector *connector;
+ struct drm_mode_connector_set_property *conn_set_prop = data;
+ struct drm_mode_obj_set_property obj_set_prop = {
+ .value = conn_set_prop->value,
+ .prop_id = conn_set_prop->prop_id,
+ .obj_id = conn_set_prop->connector_id,
+ .obj_type = DRM_MODE_OBJECT_CONNECTOR
+ };
+
+ /* It does all the locking and checking we need */
+ return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);
+}
+
+static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t value)
+{
int ret = -EINVAL;
+ struct drm_connector *connector = obj_to_connector(obj);
+
+ /* Do DPMS ourselves */
+ if (property == connector->dev->mode_config.dpms_property) {
+ if (connector->funcs->dpms)
+ (*connector->funcs->dpms)(connector, (int)value);
+ ret = 0;
+ } else if (connector->funcs->set_property)
+ ret = connector->funcs->set_property(connector, property, value);
+
+ /* store the property value if successful */
+ if (!ret)
+ drm_connector_property_set_value(connector, property, value);
+ return ret;
+}
+
+static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t value)
+{
+ int ret = -EINVAL;
+ struct drm_crtc *crtc = obj_to_crtc(obj);
+
+ if (crtc->funcs->set_property)
+ ret = crtc->funcs->set_property(crtc, property, value);
+ if (!ret)
+ drm_object_property_set_value(obj, property, value);
+
+ return ret;
+}
+
+static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t value)
+{
+ int ret = -EINVAL;
+ struct drm_plane *plane = obj_to_plane(obj);
+
+ if (plane->funcs->set_property)
+ ret = plane->funcs->set_property(plane, property, value);
+ if (!ret)
+ drm_object_property_set_value(obj, property, value);
+
+ return ret;
+}
+
+int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_obj_get_properties *arg = data;
+ struct drm_mode_object *obj;
+ int ret = 0;
int i;
+ int copied = 0;
+ int props_count = 0;
+ uint32_t __user *props_ptr;
+ uint64_t __user *prop_values_ptr;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
mutex_lock(&dev->mode_config.mutex);
- obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR);
+ obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
if (!obj) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (!obj->properties) {
+ ret = -EINVAL;
goto out;
}
- connector = obj_to_connector(obj);
- for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
- if (connector->property_ids[i] == out_resp->prop_id)
- break;
+ props_count = obj->properties->count;
+
+ /* This ioctl is called twice, once to determine how much space is
+ * needed, and the 2nd time to fill it. */
+ if ((arg->count_props >= props_count) && props_count) {
+ copied = 0;
+ props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
+ prop_values_ptr = (uint64_t __user *)(unsigned long)
+ (arg->prop_values_ptr);
+ for (i = 0; i < props_count; i++) {
+ if (put_user(obj->properties->ids[i],
+ props_ptr + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ if (put_user(obj->properties->values[i],
+ prop_values_ptr + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
}
+ arg->count_props = props_count;
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_obj_set_property *arg = data;
+ struct drm_mode_object *arg_obj;
+ struct drm_mode_object *prop_obj;
+ struct drm_property *property;
+ int ret = -EINVAL;
+ int i;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
- if (i == DRM_CONNECTOR_MAX_PROPERTY) {
+ mutex_lock(&dev->mode_config.mutex);
+
+ arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ if (!arg_obj)
+ goto out;
+ if (!arg_obj->properties)
goto out;
- }
- obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
- if (!obj) {
+ for (i = 0; i < arg_obj->properties->count; i++)
+ if (arg_obj->properties->ids[i] == arg->prop_id)
+ break;
+
+ if (i == arg_obj->properties->count)
goto out;
- }
- property = obj_to_property(obj);
- if (property->flags & DRM_MODE_PROP_IMMUTABLE)
+ prop_obj = drm_mode_object_find(dev, arg->prop_id,
+ DRM_MODE_OBJECT_PROPERTY);
+ if (!prop_obj)
goto out;
+ property = obj_to_property(prop_obj);
- if (property->flags & DRM_MODE_PROP_RANGE) {
- if (out_resp->value < property->values[0])
- goto out;
+ if (!drm_property_change_is_valid(property, arg->value))
+ goto out;
- if (out_resp->value > property->values[1])
- goto out;
- } else {
- int found = 0;
- for (i = 0; i < property->num_values; i++) {
- if (property->values[i] == out_resp->value) {
- found = 1;
- break;
- }
- }
- if (!found) {
- goto out;
- }
+ switch (arg_obj->type) {
+ case DRM_MODE_OBJECT_CONNECTOR:
+ ret = drm_mode_connector_set_obj_prop(arg_obj, property,
+ arg->value);
+ break;
+ case DRM_MODE_OBJECT_CRTC:
+ ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
+ break;
+ case DRM_MODE_OBJECT_PLANE:
+ ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value);
+ break;
}
- /* Do DPMS ourselves */
- if (property == connector->dev->mode_config.dpms_property) {
- if (connector->funcs->dpms)
- (*connector->funcs->dpms)(connector, (int) out_resp->value);
- ret = 0;
- } else if (connector->funcs->set_property)
- ret = connector->funcs->set_property(connector, property, out_resp->value);
-
- /* store the property value if successful */
- if (!ret)
- drm_connector_property_set_value(connector, property, out_resp->value);
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -2530,7 +3317,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
-bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
+int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size)
{
crtc->gamma_size = gamma_size;
@@ -2538,10 +3325,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
if (!crtc->gamma_store) {
crtc->gamma_size = 0;
- return false;
+ return -ENOMEM;
}
- return true;
+ return 0;
}
EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
@@ -2687,6 +3474,18 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
fb = obj_to_fb(obj);
+ if (crtc->mode.hdisplay > fb->width ||
+ crtc->mode.vdisplay > fb->height ||
+ crtc->x > fb->width - crtc->mode.hdisplay ||
+ crtc->y > fb->height - crtc->mode.vdisplay) {
+ DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d.\n",
+ fb->width, fb->height,
+ crtc->mode.hdisplay, crtc->mode.vdisplay,
+ crtc->x, crtc->y);
+ ret = -ENOSPC;
+ goto out;
+ }
+
if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
ret = -ENOMEM;
spin_lock_irqsave(&dev->event_lock, flags);
@@ -2779,3 +3578,71 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
return dev->driver->dumb_destroy(file_priv, dev, args->handle);
}
+
+/*
+ * Just need to support RGB formats here for compat with code that doesn't
+ * use pixel formats directly yet.
+ */
+void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
+ int *bpp)
+{
+ switch (format) {
+ case DRM_FORMAT_RGB332:
+ case DRM_FORMAT_BGR233:
+ *depth = 8;
+ *bpp = 8;
+ break;
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XBGR1555:
+ case DRM_FORMAT_RGBX5551:
+ case DRM_FORMAT_BGRX5551:
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_RGBA5551:
+ case DRM_FORMAT_BGRA5551:
+ *depth = 15;
+ *bpp = 16;
+ break;
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_BGR565:
+ *depth = 16;
+ *bpp = 16;
+ break;
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_BGR888:
+ *depth = 24;
+ *bpp = 24;
+ break;
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRX8888:
+ *depth = 24;
+ *bpp = 32;
+ break;
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_RGBX1010102:
+ case DRM_FORMAT_BGRX1010102:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_BGRA1010102:
+ *depth = 30;
+ *bpp = 32;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_BGRA8888:
+ *depth = 32;
+ *bpp = 32;
+ break;
+ default:
+ DRM_DEBUG_KMS("unsupported pixel format\n");
+ *depth = 0;
+ *bpp = 0;
+ break;
+ }
+}
+EXPORT_SYMBOL(drm_fb_get_bpp_depth);
diff --git aosp-v3.0/drivers/gpu/drm/drm_crtc_helper.c smdk4210/drivers/gpu/drm/drm_crtc_helper.c
index 9236965..014c9b6 100644
--- aosp-v3.0/drivers/gpu/drm/drm_crtc_helper.c
+++ smdk4210/drivers/gpu/drm/drm_crtc_helper.c
@@ -29,10 +29,14 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
+#include <linux/moduleparam.h>
+
#include "drmP.h"
#include "drm_crtc.h"
+#include "drm_fourcc.h"
#include "drm_crtc_helper.h"
#include "drm_fb_helper.h"
+#include "drm_edid.h"
static bool drm_kms_helper_poll = true;
module_param_named(poll, drm_kms_helper_poll, bool, 0600);
@@ -40,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600);
static void drm_mode_validate_flag(struct drm_connector *connector,
int flags)
{
- struct drm_display_mode *mode, *t;
+ struct drm_display_mode *mode;
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
return;
- list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
!(flags & DRM_MODE_FLAG_INTERLACE))
mode->status = MODE_NO_INTERLACE;
@@ -83,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY)
{
struct drm_device *dev = connector->dev;
- struct drm_display_mode *mode, *t;
+ struct drm_display_mode *mode;
struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
int count = 0;
@@ -92,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
drm_get_connector_name(connector));
/* set all modes to the unverified state */
- list_for_each_entry_safe(mode, t, &connector->modes, head)
+ list_for_each_entry(mode, &connector->modes, head)
mode->status = MODE_UNVERIFIED;
if (connector->force) {
@@ -114,7 +118,12 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
goto prune;
}
- count = (*connector_funcs->get_modes)(connector);
+#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
+ count = drm_load_edid_firmware(connector);
+ if (count == 0)
+#endif
+ count = (*connector_funcs->get_modes)(connector);
+
if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
if (count == 0)
@@ -132,7 +141,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
drm_mode_validate_flag(connector, mode_flags);
- list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
if (mode->status == MODE_OK)
mode->status = connector_funcs->mode_valid(connector,
mode);
@@ -148,7 +157,7 @@ prune:
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
drm_get_connector_name(connector));
- list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
mode->vrefresh = drm_mode_vrefresh(mode);
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
@@ -348,6 +357,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
return true;
adjusted_mode = drm_mode_duplicate(dev, mode);
+ if (!adjusted_mode)
+ return false;
saved_hwmode = crtc->hwmode;
saved_mode = crtc->mode;
@@ -372,11 +383,13 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
encoder_funcs = encoder->helper_private;
if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
adjusted_mode))) {
+ DRM_DEBUG_KMS("Encoder fixup failed\n");
goto done;
}
}
if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) {
+ DRM_DEBUG_KMS("CRTC fixup failed\n");
goto done;
}
DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
@@ -451,6 +464,30 @@ done:
EXPORT_SYMBOL(drm_crtc_helper_set_mode);
+static int
+drm_crtc_helper_disable(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+
+ /* Decouple all encoders and their attached connectors from this crtc */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->crtc != crtc)
+ continue;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->encoder != encoder)
+ continue;
+
+ connector->encoder = NULL;
+ }
+ }
+
+ drm_helper_disable_unused_functions(dev);
+ return 0;
+}
+
/**
* drm_crtc_helper_set_config - set a new config from userspace
* @crtc: CRTC to setup
@@ -479,6 +516,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
struct drm_connector *save_connectors, *connector;
int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
+ struct drm_mode_set save_set;
int ret = 0;
int i;
@@ -504,8 +542,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
(int)set->num_connectors, set->x, set->y);
} else {
DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
- set->mode = NULL;
- set->num_connectors = 0;
+ return drm_crtc_helper_disable(set->crtc);
}
dev = set->crtc->dev;
@@ -551,6 +588,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
save_connectors[count++] = *connector;
}
+ save_set.crtc = set->crtc;
+ save_set.mode = &set->crtc->mode;
+ save_set.x = set->crtc->x;
+ save_set.y = set->crtc->y;
+ save_set.fb = set->crtc->fb;
+
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
if (set->crtc->fb != set->fb) {
@@ -560,6 +603,11 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
mode_changed = true;
} else if (set->fb == NULL) {
mode_changed = true;
+ } else if (set->fb->depth != set->crtc->fb->depth) {
+ mode_changed = true;
+ } else if (set->fb->bits_per_pixel !=
+ set->crtc->fb->bits_per_pixel) {
+ mode_changed = true;
} else
fb_changed = true;
}
@@ -670,7 +718,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
for (i = 0; i < set->num_connectors; i++) {
DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
drm_get_connector_name(set->connectors[i]));
- set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+ set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
}
}
drm_helper_disable_unused_functions(dev);
@@ -711,6 +759,12 @@ fail:
*connector = save_connectors[count++];
}
+ /* Try to restore the config */
+ if (mode_changed &&
+ !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
+ save_set.y, save_set.fb))
+ DRM_ERROR("failed to restore config after modeset failure\n");
+
kfree(save_connectors);
kfree(save_encoders);
kfree(save_crtcs);
@@ -801,13 +855,19 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
EXPORT_SYMBOL(drm_helper_connector_dpms);
int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
- struct drm_mode_fb_cmd *mode_cmd)
+ struct drm_mode_fb_cmd2 *mode_cmd)
{
+ int i;
+
fb->width = mode_cmd->width;
fb->height = mode_cmd->height;
- fb->pitch = mode_cmd->pitch;
- fb->bits_per_pixel = mode_cmd->bpp;
- fb->depth = mode_cmd->depth;
+ for (i = 0; i < 4; i++) {
+ fb->pitches[i] = mode_cmd->pitches[i];
+ fb->offsets[i] = mode_cmd->offsets[i];
+ }
+ drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
+ &fb->bits_per_pixel);
+ fb->pixel_format = mode_cmd->pixel_format;
return 0;
}
@@ -962,3 +1022,36 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
}
EXPORT_SYMBOL(drm_helper_hpd_irq_event);
+
+
+/**
+ * drm_format_num_planes - get the number of planes for format
+ * @format: pixel format (DRM_FORMAT_*)
+ *
+ * RETURNS:
+ * The number of planes used by the specified pixel format.
+ */
+int drm_format_num_planes(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_YUV410:
+ case DRM_FORMAT_YVU410:
+ case DRM_FORMAT_YUV411:
+ case DRM_FORMAT_YVU411:
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420:
+ case DRM_FORMAT_YUV422:
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YVU444:
+ return 3;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
+ return 2;
+ default:
+ return 1;
+ }
+}
+EXPORT_SYMBOL(drm_format_num_planes);
diff --git aosp-v3.0/drivers/gpu/drm/drm_debugfs.c smdk4210/drivers/gpu/drm/drm_debugfs.c
index 9d8c892..895621e 100644
--- aosp-v3.0/drivers/gpu/drm/drm_debugfs.c
+++ smdk4210/drivers/gpu/drm/drm_debugfs.c
@@ -90,7 +90,6 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
struct drm_device *dev = minor->dev;
struct dentry *ent;
struct drm_info_node *tmp;
- char name[64];
int i, ret;
for (i = 0; i < count; i++) {
@@ -109,7 +108,7 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
root, tmp, &drm_debugfs_fops);
if (!ent) {
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n",
- name, files[i].name);
+ root->d_name.name, files[i].name);
kfree(tmp);
ret = -1;
goto fail;
@@ -118,7 +117,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
tmp->minor = minor;
tmp->dent = ent;
tmp->info_ent = &files[i];
- list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+
+ mutex_lock(&minor->debugfs_lock);
+ list_add(&tmp->list, &minor->debugfs_list);
+ mutex_unlock(&minor->debugfs_lock);
}
return 0;
@@ -146,7 +148,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
char name[64];
int ret;
- INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+ INIT_LIST_HEAD(&minor->debugfs_list);
+ mutex_init(&minor->debugfs_lock);
sprintf(name, "%d", minor_id);
minor->debugfs_root = debugfs_create_dir(name, root);
if (!minor->debugfs_root) {
@@ -192,8 +195,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
struct drm_info_node *tmp;
int i;
+ mutex_lock(&minor->debugfs_lock);
for (i = 0; i < count; i++) {
- list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+ list_for_each_safe(pos, q, &minor->debugfs_list) {
tmp = list_entry(pos, struct drm_info_node, list);
if (tmp->info_ent == &files[i]) {
debugfs_remove(tmp->dent);
@@ -202,6 +206,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count,
}
}
}
+ mutex_unlock(&minor->debugfs_lock);
return 0;
}
EXPORT_SYMBOL(drm_debugfs_remove_files);
diff --git aosp-v3.0/drivers/gpu/drm/drm_drv.c smdk4210/drivers/gpu/drm/drm_drv.c
index 93a112d..4ac7199 100644
--- aosp-v3.0/drivers/gpu/drm/drm_drv.c
+++ smdk4210/drivers/gpu/drm/drm_drv.c
@@ -60,14 +60,14 @@ static int drm_version(struct drm_device *dev, void *data,
/** Ioctl table */
static struct drm_ioctl_desc drm_ioctls[] = {
- DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -124,7 +124,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
@@ -134,27 +134,37 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED)
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -385,6 +395,10 @@ long drm_ioctl(struct file *filp,
unsigned int usize, asize;
dev = file_priv->minor->dev;
+
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
atomic_inc(&dev->ioctl_count);
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
++file_priv->ioctl_count;
@@ -438,6 +452,8 @@ long drm_ioctl(struct file *filp,
goto err_i1;
}
}
+ if (asize > usize)
+ memset(kdata + usize, 0, asize - usize);
}
if (cmd & IOC_IN) {
diff --git aosp-v3.0/drivers/gpu/drm/drm_edid.c smdk4210/drivers/gpu/drm/drm_edid.c
index 1bbb85b..b807cbe 100644
--- aosp-v3.0/drivers/gpu/drm/drm_edid.c
+++ smdk4210/drivers/gpu/drm/drm_edid.c
@@ -148,8 +148,7 @@ EXPORT_SYMBOL(drm_edid_header_is_valid);
* Sanity check the EDID block (base or extension). Return 0 if the block
* doesn't check out, or 1 if it's valid.
*/
-static bool
-drm_edid_block_valid(u8 *raw_edid)
+bool drm_edid_block_valid(u8 *raw_edid)
{
int i;
u8 csum = 0;
@@ -197,11 +196,12 @@ drm_edid_block_valid(u8 *raw_edid)
bad:
if (raw_edid) {
printk(KERN_ERR "Raw EDID:\n");
- print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
- printk(KERN_ERR "\n");
+ print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
+ raw_edid, EDID_LENGTH, false);
}
return 0;
}
+EXPORT_SYMBOL(drm_edid_block_valid);
/**
* drm_edid_is_valid - sanity check EDID data
@@ -225,7 +225,6 @@ bool drm_edid_is_valid(struct edid *edid)
}
EXPORT_SYMBOL(drm_edid_is_valid);
-#define DDC_ADDR 0x50
#define DDC_SEGMENT_ADDR 0x30
/**
* Get EDID information via I2C.
@@ -265,6 +264,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
}
};
ret = i2c_transfer(adapter, msgs, 2);
+ if (ret == -ENXIO) {
+ DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
+ adapter->name);
+ break;
+ }
} while (ret != 2 && --retries);
return ret == 2 ? 0 : -1;
@@ -507,25 +511,10 @@ static void
cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure)
{
int i, n = 0;
- u8 rev = ext[0x01], d = ext[0x02];
+ u8 d = ext[0x02];
u8 *det_base = ext + d;
- switch (rev) {
- case 0:
- /* can't happen */
- return;
- case 1:
- /* have to infer how many blocks we have, check pixel clock */
- for (i = 0; i < 6; i++)
- if (det_base[18*i] || det_base[18*i+1])
- n++;
- break;
- default:
- /* explicit count */
- n = min(ext[0x03] & 0x0f, 6);
- break;
- }
-
+ n = (127 - d) / 18;
for (i = 0; i < n; i++)
cb((struct detailed_timing *)(det_base + 18 * i), closure);
}
@@ -759,7 +748,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
*/
mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
- kfree(mode);
+ drm_mode_destroy(dev, mode);
mode = drm_gtf_mode_complex(dev, hsize, vsize,
vrefresh_rate, 0, 0,
drm_gtf2_m(edid),
@@ -1318,7 +1307,9 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define HDMI_IDENTIFIER 0x000C03
#define AUDIO_BLOCK 0x01
+#define VIDEO_BLOCK 0x02
#define VENDOR_BLOCK 0x03
+#define SPEAKER_BLOCK 0x04
#define EDID_BASIC_AUDIO (1 << 6)
/**
@@ -1347,6 +1338,220 @@ u8 *drm_find_cea_extension(struct edid *edid)
}
EXPORT_SYMBOL(drm_find_cea_extension);
+static int
+do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
+{
+ struct drm_device *dev = connector->dev;
+ u8 * mode, cea_mode;
+ int modes = 0;
+
+ for (mode = db; mode < db + len; mode++) {
+ cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */
+ if (cea_mode < drm_num_cea_modes) {
+ struct drm_display_mode *newmode;
+ newmode = drm_mode_duplicate(dev,
+ &edid_cea_modes[cea_mode]);
+ if (newmode) {
+ drm_mode_probed_add(connector, newmode);
+ modes++;
+ }
+ }
+ }
+
+ return modes;
+}
+
+static int
+add_cea_modes(struct drm_connector *connector, struct edid *edid)
+{
+ u8 * cea = drm_find_cea_extension(edid);
+ u8 * db, dbl;
+ int modes = 0;
+
+ if (cea && cea[1] >= 3) {
+ for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) {
+ dbl = db[0] & 0x1f;
+ if (((db[0] & 0xe0) >> 5) == VIDEO_BLOCK)
+ modes += do_cea_modes (connector, db+1, dbl);
+ }
+ }
+
+ return modes;
+}
+
+static void
+parse_hdmi_vsdb(struct drm_connector *connector, uint8_t *db)
+{
+ connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */
+
+ connector->dvi_dual = db[6] & 1;
+ connector->max_tmds_clock = db[7] * 5;
+
+ connector->latency_present[0] = db[8] >> 7;
+ connector->latency_present[1] = (db[8] >> 6) & 1;
+ connector->video_latency[0] = db[9];
+ connector->audio_latency[0] = db[10];
+ connector->video_latency[1] = db[11];
+ connector->audio_latency[1] = db[12];
+
+ DRM_LOG_KMS("HDMI: DVI dual %d, "
+ "max TMDS clock %d, "
+ "latency present %d %d, "
+ "video latency %d %d, "
+ "audio latency %d %d\n",
+ connector->dvi_dual,
+ connector->max_tmds_clock,
+ (int) connector->latency_present[0],
+ (int) connector->latency_present[1],
+ connector->video_latency[0],
+ connector->video_latency[1],
+ connector->audio_latency[0],
+ connector->audio_latency[1]);
+}
+
+static void
+monitor_name(struct detailed_timing *t, void *data)
+{
+ if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME)
+ *(u8 **)data = t->data.other_data.data.str.str;
+}
+
+/**
+ * drm_edid_to_eld - build ELD from EDID
+ * @connector: connector corresponding to the HDMI/DP sink
+ * @edid: EDID to parse
+ *
+ * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver.
+ * Some ELD fields are left to the graphics driver caller:
+ * - Conn_Type
+ * - HDCP
+ * - Port_ID
+ */
+void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
+{
+ uint8_t *eld = connector->eld;
+ u8 *cea;
+ u8 *name;
+ u8 *db;
+ int sad_count = 0;
+ int mnl;
+ int dbl;
+
+ memset(eld, 0, sizeof(connector->eld));
+
+ cea = drm_find_cea_extension(edid);
+ if (!cea) {
+ DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
+ return;
+ }
+
+ name = NULL;
+ drm_for_each_detailed_block((u8 *)edid, monitor_name, &name);
+ for (mnl = 0; name && mnl < 13; mnl++) {
+ if (name[mnl] == 0x0a)
+ break;
+ eld[20 + mnl] = name[mnl];
+ }
+ eld[4] = (cea[1] << 5) | mnl;
+ DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20);
+
+ eld[0] = 2 << 3; /* ELD version: 2 */
+
+ eld[16] = edid->mfg_id[0];
+ eld[17] = edid->mfg_id[1];
+ eld[18] = edid->prod_code[0];
+ eld[19] = edid->prod_code[1];
+
+ if (cea[1] >= 3)
+ for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) {
+ dbl = db[0] & 0x1f;
+
+ switch ((db[0] & 0xe0) >> 5) {
+ case AUDIO_BLOCK:
+ /* Audio Data Block, contains SADs */
+ sad_count = dbl / 3;
+ memcpy(eld + 20 + mnl, &db[1], dbl);
+ break;
+ case SPEAKER_BLOCK:
+ /* Speaker Allocation Data Block */
+ eld[7] = db[1];
+ break;
+ case VENDOR_BLOCK:
+ /* HDMI Vendor-Specific Data Block */
+ if (db[1] == 0x03 && db[2] == 0x0c && db[3] == 0)
+ parse_hdmi_vsdb(connector, db);
+ break;
+ default:
+ break;
+ }
+ }
+ eld[5] |= sad_count << 4;
+ eld[2] = (20 + mnl + sad_count * 3 + 3) / 4;
+
+ DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count);
+}
+EXPORT_SYMBOL(drm_edid_to_eld);
+
+/**
+ * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond
+ * @connector: connector associated with the HDMI/DP sink
+ * @mode: the display mode
+ */
+int drm_av_sync_delay(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+ int a, v;
+
+ if (!connector->latency_present[0])
+ return 0;
+ if (!connector->latency_present[1])
+ i = 0;
+
+ a = connector->audio_latency[i];
+ v = connector->video_latency[i];
+
+ /*
+ * HDMI/DP sink doesn't support audio or video?
+ */
+ if (a == 255 || v == 255)
+ return 0;
+
+ /*
+ * Convert raw EDID values to millisecond.
+ * Treat unknown latency as 0ms.
+ */
+ if (a)
+ a = min(2 * (a - 1), 500);
+ if (v)
+ v = min(2 * (v - 1), 500);
+
+ return max(v - a, 0);
+}
+EXPORT_SYMBOL(drm_av_sync_delay);
+
+/**
+ * drm_select_eld - select one ELD from multiple HDMI/DP sinks
+ * @encoder: the encoder just changed display mode
+ * @mode: the adjusted display mode
+ *
+ * It's possible for one encoder to be associated with multiple HDMI/DP sinks.
+ * The policy is now hard coded to simply use the first HDMI/DP sink's ELD.
+ */
+struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ struct drm_connector *connector;
+ struct drm_device *dev = encoder->dev;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ if (connector->encoder == encoder && connector->eld[0])
+ return connector;
+
+ return NULL;
+}
+EXPORT_SYMBOL(drm_select_eld);
+
/**
* drm_detect_hdmi_monitor - detect whether monitor is hdmi.
* @edid: monitor EDID information
@@ -1451,6 +1656,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio);
static void drm_add_display_info(struct edid *edid,
struct drm_display_info *info)
{
+ u8 *edid_ext;
+
info->width_mm = edid->width_cm * 10;
info->height_mm = edid->height_cm * 10;
@@ -1495,6 +1702,13 @@ static void drm_add_display_info(struct edid *edid,
info->color_formats = DRM_COLOR_FORMAT_YCRCB444;
if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422)
info->color_formats = DRM_COLOR_FORMAT_YCRCB422;
+
+ /* Get data from CEA blocks if present */
+ edid_ext = drm_find_cea_extension(edid);
+ if (!edid_ext)
+ return;
+
+ info->cea_rev = edid_ext[1];
}
/**
@@ -1541,6 +1755,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
num_modes += add_standard_modes(connector, edid);
num_modes += add_established_modes(connector, edid);
num_modes += add_inferred_modes(connector, edid);
+ num_modes += add_cea_modes(connector, edid);
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
edid_fixup_preferred(connector, quirks);
diff --git aosp-v3.0/drivers/gpu/drm/drm_edid_modes.h smdk4210/drivers/gpu/drm/drm_edid_modes.h
index 5f20644..a91ffb1 100644
--- aosp-v3.0/drivers/gpu/drm/drm_edid_modes.h
+++ smdk4210/drivers/gpu/drm/drm_edid_modes.h
@@ -378,3 +378,287 @@ static const struct {
{ 1920, 1440, 75, 0 },
};
static const int num_est3_modes = sizeof(est3_modes) / sizeof(est3_modes[0]);
+
+/*
+ * Probably taken from CEA-861 spec.
+ * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.
+ */
+static const struct drm_display_mode edid_cea_modes[] = {
+ /* 640x480@60Hz */
+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
+ 752, 800, 0, 480, 490, 492, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x480@60Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x480@60Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1280x720@60Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080i@60Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x480i@60Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x480i@60Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x240@60Hz */
+ { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ 1602, 1716, 0, 240, 244, 247, 262, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x240@60Hz */
+ { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478,
+ 1602, 1716, 0, 240, 244, 247, 262, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x480i@60Hz */
+ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ 3204, 3432, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 2880x480i@60Hz */
+ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ 3204, 3432, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 2880x240@60Hz */
+ { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ 3204, 3432, 0, 240, 244, 247, 262, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x240@60Hz */
+ { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956,
+ 3204, 3432, 0, 240, 244, 247, 262, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x480@60Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
+ 1596, 1716, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x480@60Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472,
+ 1596, 1716, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1920x1080@60Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 720x576@50Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x576@50Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1280x720@50Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080i@50Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x576i@50Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x576i@50Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x288@50Hz */
+ { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ 1590, 1728, 0, 288, 290, 293, 312, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x288@50Hz */
+ { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464,
+ 1590, 1728, 0, 288, 290, 293, 312, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x576i@50Hz */
+ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ 3180, 3456, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 2880x576i@50Hz */
+ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ 3180, 3456, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 2880x288@50Hz */
+ { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ 3180, 3456, 0, 288, 290, 293, 312, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x288@50Hz */
+ { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928,
+ 3180, 3456, 0, 288, 290, 293, 312, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x576@50Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
+ 1592, 1728, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x576@50Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
+ 1592, 1728, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1920x1080@50Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080@24Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
+ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080@25Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080@30Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 2880x480@60Hz */
+ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
+ 3192, 3432, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x480@60Hz */
+ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944,
+ 3192, 3432, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x576@50Hz */
+ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
+ 3184, 3456, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 2880x576@50Hz */
+ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928,
+ 3184, 3456, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1920x1080i@50Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952,
+ 2120, 2304, 0, 1080, 1126, 1136, 1250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1920x1080i@100Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1280x720@100Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 720x576@100Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x576@100Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x576i@100Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x576i@100Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1920x1080i@120Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1280x720@120Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 720x480@120Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x480@120Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x480i@120Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x480i@120Hz */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 720x576@200Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x576@200Hz */
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732,
+ 796, 864, 0, 576, 581, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x576i@200Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x576i@200Hz */
+ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464,
+ 1590, 1728, 0, 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 720x480@240Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 720x480@240Hz */
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+ /* 1440x480i@240 */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1440x480i@240 */
+ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478,
+ 1602, 1716, 0, 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
+ DRM_MODE_FLAG_INTERLACE) },
+ /* 1280x720@24Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1280x720@25Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
+ 3740, 3960, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1280x720@30Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080@120Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ /* 1920x1080@100Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+static const int drm_num_cea_modes =
+ sizeof (edid_cea_modes) / sizeof (edid_cea_modes[0]);
diff --git aosp-v3.0/drivers/gpu/drm/drm_encoder_slave.c smdk4210/drivers/gpu/drm/drm_encoder_slave.c
index d62c064..fb94355 100644
--- aosp-v3.0/drivers/gpu/drm/drm_encoder_slave.c
+++ smdk4210/drivers/gpu/drm/drm_encoder_slave.c
@@ -24,6 +24,8 @@
*
*/
+#include <linux/module.h>
+
#include "drm_encoder_slave.h"
/**
diff --git aosp-v3.0/drivers/gpu/drm/drm_fb_helper.c smdk4210/drivers/gpu/drm/drm_fb_helper.c
index a9dcdc7..a0d6e89 100644
--- aosp-v3.0/drivers/gpu/drm/drm_fb_helper.c
+++ smdk4210/drivers/gpu/drm/drm_fb_helper.c
@@ -31,6 +31,7 @@
#include <linux/sysrq.h>
#include <linux/slab.h>
#include <linux/fb.h>
+#include <linux/module.h>
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_fb_helper.h"
@@ -254,9 +255,15 @@ bool drm_fb_helper_force_kernel_mode(void)
int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
void *panic_str)
{
+ /*
+ * It's a waste of time and effort to switch back to text console
+ * if the kernel should reboot before panic messages can be seen.
+ */
+ if (panic_timeout < 0)
+ return 0;
+
printk(KERN_ERR "panic occurred, switching back to text console\n");
return drm_fb_helper_force_kernel_mode();
- return 0;
}
EXPORT_SYMBOL(drm_fb_helper_panic);
@@ -299,117 +306,57 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif
-static void drm_fb_helper_on(struct fb_info *info)
+static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
{
struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
- struct drm_crtc_helper_funcs *crtc_funcs;
struct drm_connector *connector;
- struct drm_encoder *encoder;
int i, j;
/*
- * For each CRTC in this fb, turn the crtc on then,
- * find all associated encoders and turn them on.
+ * For each CRTC in this fb, turn the connectors on/off.
*/
mutex_lock(&dev->mode_config.mutex);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
- crtc_funcs = crtc->helper_private;
if (!crtc->enabled)
continue;
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-
- /* Walk the connectors & encoders on this fb turning them on */
+ /* Walk the connectors & encoders on this fb turning them on/off */
for (j = 0; j < fb_helper->connector_count; j++) {
connector = fb_helper->connector_info[j]->connector;
- connector->dpms = DRM_MODE_DPMS_ON;
+ drm_helper_connector_dpms(connector, dpms_mode);
drm_connector_property_set_value(connector,
- dev->mode_config.dpms_property,
- DRM_MODE_DPMS_ON);
- }
- /* Found a CRTC on this fb, now find encoders */
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc) {
- struct drm_encoder_helper_funcs *encoder_funcs;
-
- encoder_funcs = encoder->helper_private;
- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
- }
+ dev->mode_config.dpms_property, dpms_mode);
}
}
mutex_unlock(&dev->mode_config.mutex);
}
-static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
-{
- struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
- struct drm_crtc *crtc;
- struct drm_crtc_helper_funcs *crtc_funcs;
- struct drm_connector *connector;
- struct drm_encoder *encoder;
- int i, j;
-
- /*
- * For each CRTC in this fb, find all associated encoders
- * and turn them off, then turn off the CRTC.
- */
- mutex_lock(&dev->mode_config.mutex);
- for (i = 0; i < fb_helper->crtc_count; i++) {
- crtc = fb_helper->crtc_info[i].mode_set.crtc;
- crtc_funcs = crtc->helper_private;
-
- if (!crtc->enabled)
- continue;
-
- /* Walk the connectors on this fb and mark them off */
- for (j = 0; j < fb_helper->connector_count; j++) {
- connector = fb_helper->connector_info[j]->connector;
- connector->dpms = dpms_mode;
- drm_connector_property_set_value(connector,
- dev->mode_config.dpms_property,
- dpms_mode);
- }
- /* Found a CRTC on this fb, now find encoders */
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (encoder->crtc == crtc) {
- struct drm_encoder_helper_funcs *encoder_funcs;
-
- encoder_funcs = encoder->helper_private;
- encoder_funcs->dpms(encoder, dpms_mode);
- }
- }
- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
- }
- mutex_unlock(&dev->mode_config.mutex);
-}
-
int drm_fb_helper_blank(int blank, struct fb_info *info)
{
switch (blank) {
/* Display: On; HSync: On, VSync: On */
case FB_BLANK_UNBLANK:
- drm_fb_helper_on(info);
+ drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
break;
/* Display: Off; HSync: On, VSync: On */
case FB_BLANK_NORMAL:
- drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+ drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
break;
/* Display: Off; HSync: Off, VSync: On */
case FB_BLANK_HSYNC_SUSPEND:
- drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+ drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
break;
/* Display: Off; HSync: On, VSync: Off */
case FB_BLANK_VSYNC_SUSPEND:
- drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
+ drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
break;
/* Display: Off; HSync: Off, VSync: Off */
case FB_BLANK_POWERDOWN:
- drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
+ drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
break;
}
return 0;
@@ -423,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
for (i = 0; i < helper->connector_count; i++)
kfree(helper->connector_info[i]);
kfree(helper->connector_info);
- for (i = 0; i < helper->crtc_count; i++)
+ for (i = 0; i < helper->crtc_count; i++) {
kfree(helper->crtc_info[i].mode_set.connectors);
+ if (helper->crtc_info[i].mode_set.mode)
+ drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
+ }
kfree(helper->crtc_info);
}
@@ -467,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,
i = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- fb_helper->crtc_info[i].crtc_id = crtc->base.id;
fb_helper->crtc_info[i].mode_set.crtc = crtc;
i++;
}
- fb_helper->conn_limit = max_conn_count;
+
return 0;
out_free:
drm_fb_helper_crtc_free(fb_helper);
diff --git aosp-v3.0/drivers/gpu/drm/drm_fops.c smdk4210/drivers/gpu/drm/drm_fops.c
index c42e12c..7348a3d 100644
--- aosp-v3.0/drivers/gpu/drm/drm_fops.c
+++ smdk4210/drivers/gpu/drm/drm_fops.c
@@ -37,6 +37,7 @@
#include "drmP.h"
#include <linux/poll.h>
#include <linux/slab.h>
+#include <linux/module.h>
/* from BKL pushdown: note that nothing else serializes idr_find() */
DEFINE_MUTEX(drm_global_mutex);
@@ -132,6 +133,9 @@ int drm_open(struct inode *inode, struct file *filp)
if (!(dev = minor->dev))
return -ENODEV;
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
retcode = drm_open_helper(inode, filp, dev);
if (!retcode) {
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
@@ -180,8 +184,11 @@ int drm_stub_open(struct inode *inode, struct file *filp)
if (!(dev = minor->dev))
goto out;
+ if (drm_device_is_unplugged(dev))
+ goto out;
+
old_fops = filp->f_op;
- filp->f_op = fops_get(&dev->driver->fops);
+ filp->f_op = fops_get(dev->driver->fops);
if (filp->f_op == NULL) {
filp->f_op = old_fops;
goto out;
@@ -578,6 +585,8 @@ int drm_release(struct inode *inode, struct file *filp)
retcode = -EBUSY;
} else
retcode = drm_lastclose(dev);
+ if (drm_device_is_unplugged(dev))
+ drm_put_dev(dev);
}
mutex_unlock(&drm_global_mutex);
diff --git aosp-v3.0/drivers/gpu/drm/drm_gem.c smdk4210/drivers/gpu/drm/drm_gem.c
index 4012fe4..83114b5 100644
--- aosp-v3.0/drivers/gpu/drm/drm_gem.c
+++ smdk4210/drivers/gpu/drm/drm_gem.c
@@ -35,6 +35,7 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
#include "drmP.h"
/** @file drm_gem.c
@@ -129,7 +130,7 @@ drm_gem_destroy(struct drm_device *dev)
}
/**
- * Initialize an already allocate GEM object of the specified size with
+ * Initialize an already allocated GEM object of the specified size with
* shmfs backing store.
*/
int drm_gem_object_init(struct drm_device *dev,
@@ -140,7 +141,7 @@ int drm_gem_object_init(struct drm_device *dev,
obj->dev = dev;
obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
if (IS_ERR(obj->filp))
- return -ENOMEM;
+ return PTR_ERR(obj->filp);
kref_init(&obj->refcount);
atomic_set(&obj->handle_count, 0);
@@ -151,6 +152,27 @@ int drm_gem_object_init(struct drm_device *dev,
EXPORT_SYMBOL(drm_gem_object_init);
/**
+ * Initialize an already allocated GEM object of the specified size with
+ * no GEM provided backing store. Instead the caller is responsible for
+ * backing the object and handling it.
+ */
+int drm_gem_private_object_init(struct drm_device *dev,
+ struct drm_gem_object *obj, size_t size)
+{
+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
+
+ obj->dev = dev;
+ obj->filp = NULL;
+
+ kref_init(&obj->refcount);
+ atomic_set(&obj->handle_count, 0);
+ obj->size = size;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_gem_private_object_init);
+
+/**
* Allocate a GEM object of the specified size with shmfs backing store
*/
struct drm_gem_object *
@@ -211,6 +233,12 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
idr_remove(&filp->object_idr, handle);
spin_unlock(&filp->table_lock);
+ if (obj->import_attach)
+ drm_prime_remove_imported_buf_handle(&filp->prime,
+ obj->import_attach->dmabuf);
+
+ if (dev->driver->gem_close_object)
+ dev->driver->gem_close_object(obj, filp);
drm_gem_object_handle_unreference_unlocked(obj);
return 0;
@@ -227,7 +255,8 @@ drm_gem_handle_create(struct drm_file *file_priv,
struct drm_gem_object *obj,
u32 *handlep)
{
- int ret;
+ struct drm_device *dev = obj->dev;
+ int ret;
/*
* Get the user-visible handle using idr.
@@ -248,10 +277,107 @@ again:
return ret;
drm_gem_object_handle_reference(obj);
+
+ if (dev->driver->gem_open_object) {
+ ret = dev->driver->gem_open_object(obj, file_priv);
+ if (ret) {
+ drm_gem_handle_delete(file_priv, *handlep);
+ return ret;
+ }
+ }
+
return 0;
}
EXPORT_SYMBOL(drm_gem_handle_create);
+
+/**
+ * drm_gem_free_mmap_offset - release a fake mmap offset for an object
+ * @obj: obj in question
+ *
+ * This routine frees fake offsets allocated by drm_gem_create_mmap_offset().
+ */
+void
+drm_gem_free_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list = &obj->map_list;
+
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+ drm_mm_put_block(list->file_offset_node);
+ kfree(list->map);
+ list->map = NULL;
+}
+EXPORT_SYMBOL(drm_gem_free_mmap_offset);
+
+/**
+ * drm_gem_create_mmap_offset - create a fake mmap offset for an object
+ * @obj: obj in question
+ *
+ * GEM memory mapping works by handing back to userspace a fake mmap offset
+ * it can use in a subsequent mmap(2) call. The DRM core code then looks
+ * up the object based on the offset and sets up the various memory mapping
+ * structures.
+ *
+ * This routine allocates and attaches a fake offset for @obj.
+ */
+int
+drm_gem_create_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+ struct drm_local_map *map;
+ int ret = 0;
+
+ /* Set the object up for mmap'ing */
+ list = &obj->map_list;
+ list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
+ if (!list->map)
+ return -ENOMEM;
+
+ map = list->map;
+ map->type = _DRM_GEM;
+ map->size = obj->size;
+ map->handle = obj;
+
+ /* Get a DRM GEM mmap offset allocated... */
+ list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
+ obj->size / PAGE_SIZE, 0, 0);
+
+ if (!list->file_offset_node) {
+ DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
+ ret = -ENOSPC;
+ goto out_free_list;
+ }
+
+ list->file_offset_node = drm_mm_get_block(list->file_offset_node,
+ obj->size / PAGE_SIZE, 0);
+ if (!list->file_offset_node) {
+ ret = -ENOMEM;
+ goto out_free_list;
+ }
+
+ list->hash.key = list->file_offset_node->start;
+ ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
+ if (ret) {
+ DRM_ERROR("failed to add to map hash\n");
+ goto out_free_mm;
+ }
+
+ return 0;
+
+out_free_mm:
+ drm_mm_put_block(list->file_offset_node);
+out_free_list:
+ kfree(list->map);
+ list->map = NULL;
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_gem_create_mmap_offset);
+
/** Returns a reference to the object named by the handle. */
struct drm_gem_object *
drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
@@ -402,7 +528,16 @@ drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
static int
drm_gem_object_release_handle(int id, void *ptr, void *data)
{
+ struct drm_file *file_priv = data;
struct drm_gem_object *obj = ptr;
+ struct drm_device *dev = obj->dev;
+
+ if (obj->import_attach)
+ drm_prime_remove_imported_buf_handle(&file_priv->prime,
+ obj->import_attach->dmabuf);
+
+ if (dev->driver->gem_close_object)
+ dev->driver->gem_close_object(obj, file_priv);
drm_gem_object_handle_unreference_unlocked(obj);
@@ -418,7 +553,7 @@ void
drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
{
idr_for_each(&file_private->object_idr,
- &drm_gem_object_release_handle, NULL);
+ &drm_gem_object_release_handle, file_private);
idr_remove_all(&file_private->object_idr);
idr_destroy(&file_private->object_idr);
@@ -427,7 +562,8 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
void
drm_gem_object_release(struct drm_gem_object *obj)
{
- fput(obj->filp);
+ if (obj->filp)
+ fput(obj->filp);
}
EXPORT_SYMBOL(drm_gem_object_release);
@@ -534,6 +670,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_hash_item *hash;
int ret = 0;
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
mutex_lock(&dev->struct_mutex);
if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) {
@@ -573,7 +712,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
*/
drm_gem_object_reference(obj);
- vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
out_unlock:
diff --git aosp-v3.0/drivers/gpu/drm/drm_ioc32.c smdk4210/drivers/gpu/drm/drm_ioc32.c
index 4a058c7..e530394 100644
--- aosp-v3.0/drivers/gpu/drm/drm_ioc32.c
+++ smdk4210/drivers/gpu/drm/drm_ioc32.c
@@ -314,7 +314,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
if (err)
return err;
- if (__get_user(c32.auth, &client->auth)
+ if (__get_user(c32.idx, &client->idx)
+ || __get_user(c32.auth, &client->auth)
|| __get_user(c32.pid, &client->pid)
|| __get_user(c32.uid, &client->uid)
|| __get_user(c32.magic, &client->magic)
diff --git aosp-v3.0/drivers/gpu/drm/drm_ioctl.c smdk4210/drivers/gpu/drm/drm_ioctl.c
index 904d7e9..033a60b 100644
--- aosp-v3.0/drivers/gpu/drm/drm_ioctl.c
+++ smdk4210/drivers/gpu/drm/drm_ioctl.c
@@ -158,14 +158,11 @@ int drm_getmap(struct drm_device *dev, void *data,
int i;
idx = map->offset;
-
- mutex_lock(&dev->struct_mutex);
- if (idx < 0) {
- mutex_unlock(&dev->struct_mutex);
+ if (idx < 0)
return -EINVAL;
- }
i = 0;
+ mutex_lock(&dev->struct_mutex);
list_for_each(list, &dev->maplist) {
if (i == idx) {
r_list = list_entry(list, struct drm_map_list, head);
@@ -211,9 +208,9 @@ int drm_getclient(struct drm_device *dev, void *data,
int i;
idx = client->idx;
- mutex_lock(&dev->struct_mutex);
-
i = 0;
+
+ mutex_lock(&dev->struct_mutex);
list_for_each_entry(pt, &dev->filelist, lhead) {
if (i++ >= idx) {
client->auth = pt->authenticated;
@@ -249,8 +246,6 @@ int drm_getstats(struct drm_device *dev, void *data,
memset(stats, 0, sizeof(*stats));
- mutex_lock(&dev->struct_mutex);
-
for (i = 0; i < dev->counters; i++) {
if (dev->types[i] == _DRM_STAT_LOCK)
stats->data[i].value =
@@ -262,8 +257,6 @@ int drm_getstats(struct drm_device *dev, void *data,
stats->count = dev->counters;
- mutex_unlock(&dev->struct_mutex);
-
return 0;
}
@@ -283,6 +276,12 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
case DRM_CAP_VBLANK_HIGH_CRTC:
req->value = 1;
break;
+ case DRM_CAP_DUMB_PREFERRED_DEPTH:
+ req->value = dev->mode_config.preferred_depth;
+ break;
+ case DRM_CAP_DUMB_PREFER_SHADOW:
+ req->value = dev->mode_config.prefer_shadow;
+ break;
default:
return -EINVAL;
}
@@ -353,3 +352,4 @@ int drm_noop(struct drm_device *dev, void *data,
DRM_DEBUG("\n");
return 0;
}
+EXPORT_SYMBOL(drm_noop);
diff --git aosp-v3.0/drivers/gpu/drm/drm_irq.c smdk4210/drivers/gpu/drm/drm_irq.c
index 2022a5c..830dcef 100644
--- aosp-v3.0/drivers/gpu/drm/drm_irq.c
+++ smdk4210/drivers/gpu/drm/drm_irq.c
@@ -109,10 +109,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
/* Prevent vblank irq processing while disabling vblank irqs,
* so no updates of timestamps or count can happen after we've
* disabled. Needed to prevent races in case of delayed irq's.
- * Disable preemption, so vblank_time_lock is held as short as
- * possible, even under a kernel with PREEMPT_RT patches.
*/
- preempt_disable();
spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
dev->driver->disable_vblank(dev, crtc);
@@ -163,7 +160,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
clear_vblank_timestamps(dev, crtc);
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
- preempt_enable();
}
static void vblank_disable_fn(unsigned long arg)
@@ -291,11 +287,14 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
if (!dev->irq_enabled)
return;
- if (state)
- dev->driver->irq_uninstall(dev);
- else {
- dev->driver->irq_preinstall(dev);
- dev->driver->irq_postinstall(dev);
+ if (state) {
+ if (dev->driver->irq_uninstall)
+ dev->driver->irq_uninstall(dev);
+ } else {
+ if (dev->driver->irq_preinstall)
+ dev->driver->irq_preinstall(dev);
+ if (dev->driver->irq_postinstall)
+ dev->driver->irq_postinstall(dev);
}
}
@@ -305,7 +304,7 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
* \param dev DRM device.
*
* Initializes the IRQ related data. Installs the handler, calling the driver
- * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
+ * \c irq_preinstall() and \c irq_postinstall() functions
* before and after the installation.
*/
int drm_irq_install(struct drm_device *dev)
@@ -338,7 +337,8 @@ int drm_irq_install(struct drm_device *dev)
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
/* Before installing handler */
- dev->driver->irq_preinstall(dev);
+ if (dev->driver->irq_preinstall)
+ dev->driver->irq_preinstall(dev);
/* Install handler */
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
@@ -363,11 +363,16 @@ int drm_irq_install(struct drm_device *dev)
vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
/* After installing handler */
- ret = dev->driver->irq_postinstall(dev);
+ if (dev->driver->irq_postinstall)
+ ret = dev->driver->irq_postinstall(dev);
+
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ vga_client_register(dev->pdev, NULL, NULL, NULL);
+ free_irq(drm_dev_to_irq(dev), dev);
}
return ret;
@@ -379,7 +384,7 @@ EXPORT_SYMBOL(drm_irq_install);
*
* \param dev DRM device.
*
- * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
+ * Calls the driver's \c irq_uninstall() function, and stops the irq.
*/
int drm_irq_uninstall(struct drm_device *dev)
{
@@ -397,13 +402,16 @@ int drm_irq_uninstall(struct drm_device *dev)
/*
* Wake up any waiters so they don't hang.
*/
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
- for (i = 0; i < dev->num_crtcs; i++) {
- DRM_WAKEUP(&dev->vbl_queue[i]);
- dev->vblank_enabled[i] = 0;
- dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
+ if (dev->num_crtcs) {
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ for (i = 0; i < dev->num_crtcs; i++) {
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] =
+ dev->driver->get_vblank_counter(dev, i);
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
if (!irq_enabled)
return -EINVAL;
@@ -413,7 +421,8 @@ int drm_irq_uninstall(struct drm_device *dev)
if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL);
- dev->driver->irq_uninstall(dev);
+ if (dev->driver->irq_uninstall)
+ dev->driver->irq_uninstall(dev);
free_irq(drm_dev_to_irq(dev), dev);
@@ -875,10 +884,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
- /* Disable preemption while holding vblank_time_lock. Do
- * it explicitely to guard against PREEMPT_RT kernel.
- */
- preempt_disable();
spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
if (!dev->vblank_enabled[crtc]) {
/* Enable vblank irqs under vblank_time_lock protection.
@@ -898,7 +903,6 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
}
}
spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
- preempt_enable();
} else {
if (!dev->vblank_enabled[crtc]) {
atomic_dec(&dev->vblank_refcount[crtc]);
@@ -1114,6 +1118,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
trace_drm_vblank_event_delivered(current->pid, pipe,
vblwait->request.sequence);
} else {
+ /* drm_handle_vblank_events will call drm_vblank_put */
list_add_tail(&e->base.link, &dev->vblank_event_list);
vblwait->reply.sequence = vblwait->request.sequence;
}
@@ -1194,8 +1199,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
goto done;
}
- if (flags & _DRM_VBLANK_EVENT)
+ if (flags & _DRM_VBLANK_EVENT) {
+ /* must hold on to the vblank ref until the event fires
+ * drm_vblank_put will be called asynchronously
+ */
return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
+ }
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
(seq - vblwait->request.sequence) <= (1<<23)) {
diff --git aosp-v3.0/drivers/gpu/drm/drm_lock.c smdk4210/drivers/gpu/drm/drm_lock.c
index 632ae24..b107e1d 100644
--- aosp-v3.0/drivers/gpu/drm/drm_lock.c
+++ smdk4210/drivers/gpu/drm/drm_lock.c
@@ -345,6 +345,7 @@ void drm_idlelock_take(struct drm_lock_data *lock_data)
}
spin_unlock_bh(&lock_data->spinlock);
}
+EXPORT_SYMBOL(drm_idlelock_take);
void drm_idlelock_release(struct drm_lock_data *lock_data)
{
@@ -364,6 +365,7 @@ void drm_idlelock_release(struct drm_lock_data *lock_data)
}
spin_unlock_bh(&lock_data->spinlock);
}
+EXPORT_SYMBOL(drm_idlelock_release);
int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv)
{
diff --git aosp-v3.0/drivers/gpu/drm/drm_memory.c smdk4210/drivers/gpu/drm/drm_memory.c
index c9b8050..21a554d 100644
--- aosp-v3.0/drivers/gpu/drm/drm_memory.c
+++ smdk4210/drivers/gpu/drm/drm_memory.c
@@ -36,25 +36,6 @@
#include <linux/highmem.h>
#include "drmP.h"
-/**
- * Called when "/proc/dri/%dev%/mem" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param len requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * No-op.
- */
-int drm_mem_info(char *buf, char **start, off_t offset,
- int len, int *eof, void *data)
-{
- return 0;
-}
-
#if __OS_HAS_AGP
static void *agp_remap(unsigned long offset, unsigned long size,
struct drm_device * dev)
diff --git aosp-v3.0/drivers/gpu/drm/drm_modes.c smdk4210/drivers/gpu/drm/drm_modes.c
index c2d32f2..742abe6 100644
--- aosp-v3.0/drivers/gpu/drm/drm_modes.c
+++ smdk4210/drivers/gpu/drm/drm_modes.c
@@ -685,8 +685,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
p->crtc_vsync_end /= 2;
p->crtc_vtotal /= 2;
}
-
- p->crtc_vtotal |= 1;
}
if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
@@ -715,6 +713,27 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo);
/**
+ * drm_mode_copy - copy the mode
+ * @dst: mode to overwrite
+ * @src: mode to copy
+ *
+ * LOCKING:
+ * None.
+ *
+ * Copy an existing mode into another mode, preserving the object id
+ * of the destination mode.
+ */
+void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)
+{
+ int id = dst->base.id;
+
+ *dst = *src;
+ dst->base.id = id;
+ INIT_LIST_HEAD(&dst->head);
+}
+EXPORT_SYMBOL(drm_mode_copy);
+
+/**
* drm_mode_duplicate - allocate and duplicate an existing mode
* @m: mode to duplicate
*
@@ -728,16 +747,13 @@ struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
const struct drm_display_mode *mode)
{
struct drm_display_mode *nmode;
- int new_id;
nmode = drm_mode_create(dev);
if (!nmode)
return NULL;
- new_id = nmode->base.id;
- *nmode = *mode;
- nmode->base.id = new_id;
- INIT_LIST_HEAD(&nmode->head);
+ drm_mode_copy(nmode, mode);
+
return nmode;
}
EXPORT_SYMBOL(drm_mode_duplicate);
@@ -994,9 +1010,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
{
const char *name;
unsigned int namelen;
- int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
+ bool res_specified = false, bpp_specified = false, refresh_specified = false;
unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
- int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
+ bool yres_specified = false, cvt = false, rb = false;
+ bool interlace = false, margins = false, was_digit = false;
int i;
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
@@ -1015,54 +1032,65 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
case '@':
- namelen = i;
if (!refresh_specified && !bpp_specified &&
- !yres_specified) {
+ !yres_specified && !cvt && !rb && was_digit) {
refresh = simple_strtol(&name[i+1], NULL, 10);
- refresh_specified = 1;
- if (cvt || rb)
- cvt = 0;
+ refresh_specified = true;
+ was_digit = false;
} else
goto done;
break;
case '-':
- namelen = i;
- if (!bpp_specified && !yres_specified) {
+ if (!bpp_specified && !yres_specified && !cvt &&
+ !rb && was_digit) {
bpp = simple_strtol(&name[i+1], NULL, 10);
- bpp_specified = 1;
- if (cvt || rb)
- cvt = 0;
+ bpp_specified = true;
+ was_digit = false;
} else
goto done;
break;
case 'x':
- if (!yres_specified) {
+ if (!yres_specified && was_digit) {
yres = simple_strtol(&name[i+1], NULL, 10);
- yres_specified = 1;
+ yres_specified = true;
+ was_digit = false;
} else
goto done;
case '0' ... '9':
+ was_digit = true;
break;
case 'M':
- if (!yres_specified)
- cvt = 1;
+ if (yres_specified || cvt || was_digit)
+ goto done;
+ cvt = true;
break;
case 'R':
- if (cvt)
- rb = 1;
+ if (yres_specified || cvt || rb || was_digit)
+ goto done;
+ rb = true;
break;
case 'm':
- if (!cvt)
- margins = 1;
+ if (cvt || yres_specified || was_digit)
+ goto done;
+ margins = true;
break;
case 'i':
- if (!cvt)
- interlace = 1;
+ if (cvt || yres_specified || was_digit)
+ goto done;
+ interlace = true;
break;
case 'e':
+ if (yres_specified || bpp_specified || refresh_specified ||
+ was_digit || (force != DRM_FORCE_UNSPECIFIED))
+ goto done;
+
force = DRM_FORCE_ON;
break;
case 'D':
+ if (yres_specified || bpp_specified || refresh_specified ||
+ was_digit || (force != DRM_FORCE_UNSPECIFIED))
+ goto done;
+
if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
(connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
force = DRM_FORCE_ON;
@@ -1070,17 +1098,37 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
force = DRM_FORCE_ON_DIGITAL;
break;
case 'd':
+ if (yres_specified || bpp_specified || refresh_specified ||
+ was_digit || (force != DRM_FORCE_UNSPECIFIED))
+ goto done;
+
force = DRM_FORCE_OFF;
break;
default:
goto done;
}
}
+
if (i < 0 && yres_specified) {
- xres = simple_strtol(name, NULL, 10);
- res_specified = 1;
+ char *ch;
+ xres = simple_strtol(name, &ch, 10);
+ if ((ch != NULL) && (*ch == 'x'))
+ res_specified = true;
+ else
+ i = ch - name;
+ } else if (!yres_specified && was_digit) {
+ /* catch mode that begins with digits but has no 'x' */
+ i = 0;
}
done:
+ if (i >= 0) {
+ printk(KERN_WARNING
+ "parse error at position %i in video mode '%s'\n",
+ i, name);
+ mode->specified = false;
+ return false;
+ }
+
if (res_specified) {
mode->specified = true;
mode->xres = xres;
@@ -1096,9 +1144,10 @@ done:
mode->bpp_specified = true;
mode->bpp = bpp;
}
- mode->rb = rb ? true : false;
- mode->cvt = cvt ? true : false;
- mode->interlace = interlace ? true : false;
+ mode->rb = rb;
+ mode->cvt = cvt;
+ mode->interlace = interlace;
+ mode->margins = margins;
mode->force = force;
return true;
diff --git aosp-v3.0/drivers/gpu/drm/drm_pci.c smdk4210/drivers/gpu/drm/drm_pci.c
index b6a19cb..7213ee4 100644
--- aosp-v3.0/drivers/gpu/drm/drm_pci.c
+++ smdk4210/drivers/gpu/drm/drm_pci.c
@@ -323,8 +323,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (ret)
goto err_g1;
- pci_set_master(pdev);
-
dev->pdev = pdev;
dev->dev = &pdev->dev;
diff --git aosp-v3.0/drivers/gpu/drm/drm_platform.c smdk4210/drivers/gpu/drm/drm_platform.c
index 7223f06..9cda314 100644
--- aosp-v3.0/drivers/gpu/drm/drm_platform.c
+++ smdk4210/drivers/gpu/drm/drm_platform.c
@@ -121,16 +121,25 @@ static const char *drm_platform_get_name(struct drm_device *dev)
static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master)
{
- int len, ret;
+ int len, ret, id;
- master->unique_len = 10 + strlen(dev->platformdev->name);
+ master->unique_len = 13 + strlen(dev->platformdev->name);
+ master->unique_size = master->unique_len;
master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
if (master->unique == NULL)
return -ENOMEM;
+ id = dev->platformdev->id;
+
+ /* if only a single instance of the platform device, id will be
+ * set to -1.. use 0 instead to avoid a funny looking bus-id:
+ */
+ if (id == -1)
+ id = 0;
+
len = snprintf(master->unique, master->unique_len,
- "platform:%s", dev->platformdev->name);
+ "platform:%s:%02d", dev->platformdev->name, id);
if (len > master->unique_len) {
DRM_ERROR("Unique buffer overflowed\n");
diff --git aosp-v3.0/drivers/gpu/drm/drm_proc.c smdk4210/drivers/gpu/drm/drm_proc.c
index 9e5b07e..0f3c4e3 100644
--- aosp-v3.0/drivers/gpu/drm/drm_proc.c
+++ smdk4210/drivers/gpu/drm/drm_proc.c
@@ -95,7 +95,6 @@ int drm_proc_create_files(struct drm_info_list *files, int count,
struct drm_device *dev = minor->dev;
struct proc_dir_entry *ent;
struct drm_info_node *tmp;
- char name[64];
int i, ret;
for (i = 0; i < count; i++) {
@@ -118,7 +117,7 @@ int drm_proc_create_files(struct drm_info_list *files, int count,
&drm_proc_fops, tmp);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
- name, files[i].name);
+ root->name, files[i].name);
list_del(&tmp->list);
kfree(tmp);
ret = -1;
diff --git aosp-v3.0/drivers/gpu/drm/drm_scatter.c smdk4210/drivers/gpu/drm/drm_scatter.c
index d15e09b..7525e03 100644
--- aosp-v3.0/drivers/gpu/drm/drm_scatter.c
+++ smdk4210/drivers/gpu/drm/drm_scatter.c
@@ -83,30 +83,26 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
if (dev->sg)
return -EINVAL;
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
- memset(entry, 0, sizeof(*entry));
pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages);
entry->pages = pages;
- entry->pagelist = kmalloc(pages * sizeof(*entry->pagelist), GFP_KERNEL);
+ entry->pagelist = kcalloc(pages, sizeof(*entry->pagelist), GFP_KERNEL);
if (!entry->pagelist) {
kfree(entry);
return -ENOMEM;
}
- memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
-
- entry->busaddr = kmalloc(pages * sizeof(*entry->busaddr), GFP_KERNEL);
+ entry->busaddr = kcalloc(pages, sizeof(*entry->busaddr), GFP_KERNEL);
if (!entry->busaddr) {
kfree(entry->pagelist);
kfree(entry);
return -ENOMEM;
}
- memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT);
if (!entry->virtual) {
diff --git aosp-v3.0/drivers/gpu/drm/drm_stub.c smdk4210/drivers/gpu/drm/drm_stub.c
index 6d7b083..aa454f8 100644
--- aosp-v3.0/drivers/gpu/drm/drm_stub.c
+++ smdk4210/drivers/gpu/drm/drm_stub.c
@@ -319,6 +319,7 @@ int drm_fill_in_dev(struct drm_device *dev,
drm_lastclose(dev);
return retcode;
}
+EXPORT_SYMBOL(drm_fill_in_dev);
/**
@@ -397,6 +398,7 @@ err_idr:
*minor = NULL;
return ret;
}
+EXPORT_SYMBOL(drm_get_minor);
/**
* Put a secondary minor number.
@@ -428,6 +430,12 @@ int drm_put_minor(struct drm_minor **minor_p)
*minor_p = NULL;
return 0;
}
+EXPORT_SYMBOL(drm_put_minor);
+
+static void drm_unplug_minor(struct drm_minor *minor)
+{
+ drm_sysfs_device_remove(minor);
+}
/**
* Called via drm_exit() at module unload time or when pci device is
@@ -492,3 +500,21 @@ void drm_put_dev(struct drm_device *dev)
kfree(dev);
}
EXPORT_SYMBOL(drm_put_dev);
+
+void drm_unplug_dev(struct drm_device *dev)
+{
+ /* for a USB device */
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_unplug_minor(dev->control);
+ drm_unplug_minor(dev->primary);
+
+ mutex_lock(&drm_global_mutex);
+
+ drm_device_set_unplugged(dev);
+
+ if (dev->open_count == 0) {
+ drm_put_dev(dev);
+ }
+ mutex_unlock(&drm_global_mutex);
+}
+EXPORT_SYMBOL(drm_unplug_dev);
diff --git aosp-v3.0/drivers/gpu/drm/drm_sysfs.c smdk4210/drivers/gpu/drm/drm_sysfs.c
index 2eee8e0..d9c3a1b 100644
--- aosp-v3.0/drivers/gpu/drm/drm_sysfs.c
+++ smdk4210/drivers/gpu/drm/drm_sysfs.c
@@ -71,7 +71,7 @@ static int drm_class_resume(struct device *dev)
return 0;
}
-static char *drm_devnode(struct device *dev, mode_t *mode)
+static char *drm_devnode(struct device *dev, umode_t *mode)
{
return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
}
@@ -453,6 +453,8 @@ void drm_sysfs_connector_remove(struct drm_connector *connector)
{
int i;
+ if (!connector->kdev.parent)
+ return;
DRM_DEBUG("removing \"%s\" from sysfs\n",
drm_get_connector_name(connector));
@@ -460,6 +462,7 @@ void drm_sysfs_connector_remove(struct drm_connector *connector)
device_remove_file(&connector->kdev, &connector_attrs[i]);
sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr);
device_unregister(&connector->kdev);
+ connector->kdev.parent = NULL;
}
EXPORT_SYMBOL(drm_sysfs_connector_remove);
@@ -532,7 +535,9 @@ err_out:
*/
void drm_sysfs_device_remove(struct drm_minor *minor)
{
- device_unregister(&minor->kdev);
+ if (minor->kdev.parent)
+ device_unregister(&minor->kdev);
+ minor->kdev.parent = NULL;
}
diff --git aosp-v3.0/drivers/gpu/drm/drm_usb.c smdk4210/drivers/gpu/drm/drm_usb.c
index 206d230..6298056 100644
--- aosp-v3.0/drivers/gpu/drm/drm_usb.c
+++ smdk4210/drivers/gpu/drm/drm_usb.c
@@ -1,7 +1,6 @@
#include "drmP.h"
#include <linux/usb.h>
-#ifdef CONFIG_USB
int drm_get_usb_dev(struct usb_interface *interface,
const struct usb_device_id *id,
struct drm_driver *driver)
@@ -114,4 +113,3 @@ void drm_usb_exit(struct drm_driver *driver,
usb_deregister(udriver);
}
EXPORT_SYMBOL(drm_usb_exit);
-#endif
diff --git aosp-v3.0/drivers/gpu/drm/drm_vm.c smdk4210/drivers/gpu/drm/drm_vm.c
index 5db96d45..51d4c4a 100644
--- aosp-v3.0/drivers/gpu/drm/drm_vm.c
+++ smdk4210/drivers/gpu/drm/drm_vm.c
@@ -518,7 +518,6 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED; /* Don't swap */
vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
return 0;
}
@@ -670,7 +669,6 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED; /* Don't swap */
vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
return 0;
}
@@ -681,6 +679,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_device *dev = priv->minor->dev;
int ret;
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
mutex_lock(&dev->struct_mutex);
ret = drm_mmap_locked(filp, vma);
mutex_unlock(&dev->struct_mutex);
diff --git aosp-v3.0/drivers/gpu/drm/i2c/ch7006_drv.c smdk4210/drivers/gpu/drm/i2c/ch7006_drv.c
index 08792a7..d3f2e87 100644
--- aosp-v3.0/drivers/gpu/drm/i2c/ch7006_drv.c
+++ smdk4210/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -24,6 +24,8 @@
*
*/
+#include <linux/module.h>
+
#include "ch7006_priv.h"
/* DRM encoder functions */
@@ -250,10 +252,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
- priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE,
- "scale", 2);
- priv->scale_property->values[0] = 0;
- priv->scale_property->values[1] = 2;
+ priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2);
drm_connector_attach_property(connector, conf->tv_select_subconnector_property,
priv->select_subconnector);
diff --git aosp-v3.0/drivers/gpu/drm/i2c/sil164_drv.c smdk4210/drivers/gpu/drm/i2c/sil164_drv.c
index 0b67732..b7d45ab 100644
--- aosp-v3.0/drivers/gpu/drm/i2c/sil164_drv.c
+++ smdk4210/drivers/gpu/drm/i2c/sil164_drv.c
@@ -24,6 +24,8 @@
*
*/
+#include <linux/module.h>
+
#include "drmP.h"
#include "drm_crtc_helper.h"
#include "drm_encoder_slave.h"
diff --git aosp-v3.0/drivers/gpu/drm/i810/i810_dma.c smdk4210/drivers/gpu/drm/i810/i810_dma.c
index 8f371e8..2c8a60c 100644
--- aosp-v3.0/drivers/gpu/drm/i810/i810_dma.c
+++ smdk4210/drivers/gpu/drm/i810/i810_dma.c
@@ -99,7 +99,6 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
buf_priv = buf->dev_private;
vma->vm_flags |= (VM_IO | VM_DONTCOPY);
- vma->vm_file = filp;
buf_priv->currently_mapped = I810_BUF_MAPPED;
@@ -222,8 +221,6 @@ static int i810_dma_cleanup(struct drm_device *dev)
pci_free_consistent(dev->pdev, PAGE_SIZE,
dev_priv->hw_status_page,
dev_priv->dma_status_page);
- /* Need to rewrite hardware status page */
- I810_WRITE(0x02080, 0x1ffff000);
}
kfree(dev->dev_private);
dev->dev_private = NULL;
@@ -1210,6 +1207,8 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags)
dev->types[8] = _DRM_STAT_SECONDARY;
dev->types[9] = _DRM_STAT_DMA;
+ pci_set_master(dev->pdev);
+
return 0;
}
diff --git aosp-v3.0/drivers/gpu/drm/i810/i810_drv.c smdk4210/drivers/gpu/drm/i810/i810_drv.c
index 6f98d05..ec12f7d 100644
--- aosp-v3.0/drivers/gpu/drm/i810/i810_drv.c
+++ smdk4210/drivers/gpu/drm/i810/i810_drv.c
@@ -30,6 +30,8 @@
* Gareth Hughes <gareth@valinux.com>
*/
+#include <linux/module.h>
+
#include "drmP.h"
#include "drm.h"
#include "i810_drm.h"
@@ -41,6 +43,17 @@ static struct pci_device_id pciidlist[] = {
i810_PCI_IDS
};
+static const struct file_operations i810_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ .llseek = noop_llseek,
+};
+
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
@@ -53,17 +66,7 @@ static struct drm_driver driver = {
.reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
.dma_quiescent = i810_driver_dma_quiescent,
.ioctls = i810_ioctls,
- .fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- .llseek = noop_llseek,
- },
-
+ .fops = &i810_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
diff --git aosp-v3.0/drivers/gpu/drm/i915/Makefile smdk4210/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..ce7fc77 100644
--- aosp-v3.0/drivers/gpu/drm/i915/Makefile
+++ smdk4210/drivers/gpu/drm/i915/Makefile
@@ -3,7 +3,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
+i915-y := i915_drv.o i915_dma.o i915_irq.o \
i915_debugfs.o \
i915_suspend.o \
i915_gem.o \
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \
+ intel_sprite.o \
intel_opregion.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
diff --git aosp-v3.0/drivers/gpu/drm/i915/dvo_ch7017.c smdk4210/drivers/gpu/drm/i915/dvo_ch7017.c
index d3e8c54..1ca799a 100644
--- aosp-v3.0/drivers/gpu/drm/i915/dvo_ch7017.c
+++ smdk4210/drivers/gpu/drm/i915/dvo_ch7017.c
@@ -227,7 +227,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
default:
DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
"slave %d.\n",
- val, adapter->name,dvo->slave_addr);
+ val, adapter->name, dvo->slave_addr);
goto fail;
}
diff --git aosp-v3.0/drivers/gpu/drm/i915/dvo_ch7xxx.c smdk4210/drivers/gpu/drm/i915/dvo_ch7xxx.c
index 7eaa94e..4a03660 100644
--- aosp-v3.0/drivers/gpu/drm/i915/dvo_ch7xxx.c
+++ smdk4210/drivers/gpu/drm/i915/dvo_ch7xxx.c
@@ -111,7 +111,7 @@ static char *ch7xxx_get_id(uint8_t vid)
/** Reads an 8 bit register */
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
{
- struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
+ struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
struct i2c_adapter *adapter = dvo->i2c_bus;
u8 out_buf[2];
u8 in_buf[2];
@@ -303,7 +303,7 @@ static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
for (i = 0; i < CH7xxx_NUM_REGS; i++) {
uint8_t val;
- if ((i % 8) == 0 )
+ if ((i % 8) == 0)
DRM_LOG_KMS("\n %02X: ", i);
ch7xxx_readb(dvo, i, &val);
DRM_LOG_KMS("%02X ", val);
diff --git aosp-v3.0/drivers/gpu/drm/i915/dvo_ivch.c smdk4210/drivers/gpu/drm/i915/dvo_ivch.c
index a12ed94..04f2893 100644
--- aosp-v3.0/drivers/gpu/drm/i915/dvo_ivch.c
+++ smdk4210/drivers/gpu/drm/i915/dvo_ivch.c
@@ -344,8 +344,8 @@ static void ivch_mode_set(struct intel_dvo_device *dvo,
(adjusted_mode->hdisplay - 1)) >> 2;
y_ratio = (((mode->vdisplay - 1) << 16) /
(adjusted_mode->vdisplay - 1)) >> 2;
- ivch_write (dvo, VR42, x_ratio);
- ivch_write (dvo, VR41, y_ratio);
+ ivch_write(dvo, VR42, x_ratio);
+ ivch_write(dvo, VR41, y_ratio);
} else {
vr01 &= ~VR01_PANEL_FIT_ENABLE;
vr40 &= ~VR40_CLOCK_GATING_ENABLE;
@@ -410,7 +410,7 @@ static void ivch_destroy(struct intel_dvo_device *dvo)
}
}
-struct intel_dvo_dev_ops ivch_ops= {
+struct intel_dvo_dev_ops ivch_ops = {
.init = ivch_init,
.dpms = ivch_dpms,
.mode_valid = ivch_mode_valid,
diff --git aosp-v3.0/drivers/gpu/drm/i915/dvo_sil164.c smdk4210/drivers/gpu/drm/i915/dvo_sil164.c
index e4b4091..a0b13a6 100644
--- aosp-v3.0/drivers/gpu/drm/i915/dvo_sil164.c
+++ smdk4210/drivers/gpu/drm/i915/dvo_sil164.c
@@ -104,7 +104,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
{
- struct sil164_priv *sil= dvo->dev_priv;
+ struct sil164_priv *sil = dvo->dev_priv;
struct i2c_adapter *adapter = dvo->i2c_bus;
uint8_t out_buf[2];
struct i2c_msg msg = {
diff --git aosp-v3.0/drivers/gpu/drm/i915/dvo_tfp410.c smdk4210/drivers/gpu/drm/i915/dvo_tfp410.c
index 8ab2855..aa2cd3e 100644
--- aosp-v3.0/drivers/gpu/drm/i915/dvo_tfp410.c
+++ smdk4210/drivers/gpu/drm/i915/dvo_tfp410.c
@@ -56,7 +56,7 @@
#define TFP410_CTL_2_MDI (1<<0)
#define TFP410_CTL_3 0x0A
-#define TFP410_CTL_3_DK_MASK (0x7<<5)
+#define TFP410_CTL_3_DK_MASK (0x7<<5)
#define TFP410_CTL_3_DK (1<<5)
#define TFP410_CTL_3_DKEN (1<<4)
#define TFP410_CTL_3_CTL_MASK (0x7<<1)
@@ -225,12 +225,12 @@ static void tfp410_mode_set(struct intel_dvo_device *dvo,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- /* As long as the basics are set up, since we don't have clock dependencies
- * in the mode setup, we can just leave the registers alone and everything
- * will work fine.
- */
- /* don't do much */
- return;
+ /* As long as the basics are set up, since we don't have clock dependencies
+ * in the mode setup, we can just leave the registers alone and everything
+ * will work fine.
+ */
+ /* don't do much */
+ return;
}
/* set the tfp410 power state */
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_debugfs.c smdk4210/drivers/gpu/drm/i915/i915_debugfs.c
index e36efdc..ab408d7 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_debugfs.c
+++ smdk4210/drivers/gpu/drm/i915/i915_debugfs.c
@@ -61,6 +61,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
const struct intel_device_info *info = INTEL_INFO(dev);
seq_printf(m, "gen: %d\n", info->gen);
+ seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev));
#define B(x) seq_printf(m, #x ": %s\n", yesno(info->x))
B(is_mobile);
B(is_i85x);
@@ -81,6 +82,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
B(supports_tv);
B(has_bsd_ring);
B(has_blt_ring);
+ B(has_llc);
#undef B
return 0;
@@ -98,12 +100,12 @@ static const char *get_pin_flag(struct drm_i915_gem_object *obj)
static const char *get_tiling_flag(struct drm_i915_gem_object *obj)
{
- switch (obj->tiling_mode) {
- default:
- case I915_TILING_NONE: return " ";
- case I915_TILING_X: return "X";
- case I915_TILING_Y: return "Y";
- }
+ switch (obj->tiling_mode) {
+ default:
+ case I915_TILING_NONE: return " ";
+ case I915_TILING_X: return "X";
+ case I915_TILING_Y: return "Y";
+ }
}
static const char *cache_level_str(int type)
@@ -119,11 +121,11 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
+ seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
- obj->base.size,
+ obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain,
obj->last_rendering_seqno,
@@ -217,7 +219,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
++mappable_count; \
} \
} \
-} while(0)
+} while (0)
static int i915_gem_object_info(struct seq_file *m, void* data)
{
@@ -499,7 +501,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
seq_printf(m, "Interrupts received: %d\n",
atomic_read(&dev_priv->irq_received));
for (i = 0; i < I915_NUM_RINGS; i++) {
- if (IS_GEN6(dev)) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, "Graphics Interrupt mask (%s): %08x\n",
dev_priv->ring[i].name,
I915_READ_IMR(&dev_priv->ring[i]));
@@ -561,45 +563,6 @@ static int i915_hws_info(struct seq_file *m, void *data)
return 0;
}
-static void i915_dump_object(struct seq_file *m,
- struct io_mapping *mapping,
- struct drm_i915_gem_object *obj)
-{
- int page, page_count, i;
-
- page_count = obj->base.size / PAGE_SIZE;
- for (page = 0; page < page_count; page++) {
- u32 *mem = io_mapping_map_wc(mapping,
- obj->gtt_offset + page * PAGE_SIZE);
- for (i = 0; i < PAGE_SIZE; i += 4)
- seq_printf(m, "%08x : %08x\n", i, mem[i / 4]);
- io_mapping_unmap(mem);
- }
-}
-
-static int i915_batchbuffer_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj;
- int ret;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
- if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) {
- seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset);
- i915_dump_object(m, dev_priv->mm.gtt_mapping, obj);
- }
- }
-
- mutex_unlock(&dev->struct_mutex);
- return 0;
-}
-
static int i915_ringbuffer_data(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -635,33 +598,40 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
+ int ret;
ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];
if (ring->size == 0)
return 0;
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
seq_printf(m, "Ring %s:\n", ring->name);
seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR);
seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR);
seq_printf(m, " Size : %08x\n", ring->size);
seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring));
seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring));
- if (IS_GEN6(dev)) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring));
seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring));
}
seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring));
seq_printf(m, " Start : %08x\n", I915_READ_START(ring));
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
static const char *ring_str(int ring)
{
switch (ring) {
- case RING_RENDER: return " render";
- case RING_BSD: return " bsd";
- case RING_BLT: return " blt";
+ case RCS: return "render";
+ case VCS: return "bsd";
+ case BCS: return "blt";
default: return "";
}
}
@@ -704,7 +674,7 @@ static void print_error_buffers(struct seq_file *m,
seq_printf(m, "%s [%d]:\n", name, count);
while (count--) {
- seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s",
+ seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s",
err->gtt_offset,
err->size,
err->read_domains,
@@ -714,6 +684,7 @@ static void print_error_buffers(struct seq_file *m,
tiling_flag(err->tiling),
dirty_flag(err->dirty),
purgeable_flag(err->purgeable),
+ err->ring != -1 ? " " : "",
ring_str(err->ring),
cache_level_str(err->cache_level));
@@ -727,6 +698,38 @@ static void print_error_buffers(struct seq_file *m,
}
}
+static void i915_ring_error_state(struct seq_file *m,
+ struct drm_device *dev,
+ struct drm_i915_error_state *error,
+ unsigned ring)
+{
+ seq_printf(m, "%s command stream:\n", ring_str(ring));
+ seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]);
+ seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]);
+ seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]);
+ seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]);
+ seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]);
+ seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
+ if (ring == RCS && INTEL_INFO(dev)->gen >= 4) {
+ seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1);
+ seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr);
+ }
+ if (INTEL_INFO(dev)->gen >= 4)
+ seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]);
+ seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]);
+ if (INTEL_INFO(dev)->gen >= 6) {
+ seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]);
+ seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
+ seq_printf(m, " SYNC_0: 0x%08x\n",
+ error->semaphore_mboxes[ring][0]);
+ seq_printf(m, " SYNC_1: 0x%08x\n",
+ error->semaphore_mboxes[ring][1]);
+ }
+ seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]);
+ seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
+ seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
+}
+
static int i915_error_state(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -734,7 +737,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_error_state *error;
unsigned long flags;
- int i, page, offset, elt;
+ int i, j, page, offset, elt;
spin_lock_irqsave(&dev_priv->error_lock, flags);
if (!dev_priv->first_error) {
@@ -749,35 +752,20 @@ static int i915_error_state(struct seq_file *m, void *unused)
seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
seq_printf(m, "EIR: 0x%08x\n", error->eir);
seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+
+ for (i = 0; i < dev_priv->num_fence_regs; i++)
+ seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
+
if (INTEL_INFO(dev)->gen >= 6) {
seq_printf(m, "ERROR: 0x%08x\n", error->error);
- seq_printf(m, "Blitter command stream:\n");
- seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd);
- seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir);
- seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr);
- seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone);
- seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno);
- seq_printf(m, "Video (BSD) command stream:\n");
- seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd);
- seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir);
- seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr);
- seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone);
- seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno);
+ seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
}
- seq_printf(m, "Render command stream:\n");
- seq_printf(m, " ACTHD: 0x%08x\n", error->acthd);
- seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir);
- seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr);
- seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone);
- if (INTEL_INFO(dev)->gen >= 4) {
- seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1);
- seq_printf(m, " INSTPS: 0x%08x\n", error->instps);
- }
- seq_printf(m, " INSTPM: 0x%08x\n", error->instpm);
- seq_printf(m, " seqno: 0x%08x\n", error->seqno);
- for (i = 0; i < dev_priv->num_fence_regs; i++)
- seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
+ i915_ring_error_state(m, dev, error, RCS);
+ if (HAS_BLT(dev))
+ i915_ring_error_state(m, dev, error, BCS);
+ if (HAS_BSD(dev))
+ i915_ring_error_state(m, dev, error, VCS);
if (error->active_bo)
print_error_buffers(m, "Active",
@@ -789,10 +777,10 @@ static int i915_error_state(struct seq_file *m, void *unused)
error->pinned_bo,
error->pinned_bo_count);
- for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
- if (error->batchbuffer[i]) {
- struct drm_i915_error_object *obj = error->batchbuffer[i];
+ for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
+ struct drm_i915_error_object *obj;
+ if ((obj = error->ring[i].batchbuffer)) {
seq_printf(m, "%s --- gtt_offset = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
@@ -804,11 +792,20 @@ static int i915_error_state(struct seq_file *m, void *unused)
}
}
}
- }
- for (i = 0; i < ARRAY_SIZE(error->ringbuffer); i++) {
- if (error->ringbuffer[i]) {
- struct drm_i915_error_object *obj = error->ringbuffer[i];
+ if (error->ring[i].num_requests) {
+ seq_printf(m, "%s --- %d requests\n",
+ dev_priv->ring[i].name,
+ error->ring[i].num_requests);
+ for (j = 0; j < error->ring[i].num_requests; j++) {
+ seq_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n",
+ error->ring[i].requests[j].seqno,
+ error->ring[i].requests[j].jiffies,
+ error->ring[i].requests[j].tail);
+ }
+ }
+
+ if ((obj = error->ring[i].ringbuffer)) {
seq_printf(m, "%s --- ringbuffer = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
@@ -841,7 +838,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u16 crstanddelay = I915_READ16(CRSTANDVID);
+ u16 crstanddelay;
+ int ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ crstanddelay = I915_READ16(CRSTANDVID);
+
+ mutex_unlock(&dev->struct_mutex);
seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
@@ -939,7 +945,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
u32 delayfreq;
- int i;
+ int ret, i;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
for (i = 0; i < 16; i++) {
delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
@@ -947,6 +957,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused)
(delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
}
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
@@ -961,24 +973,40 @@ static int i915_inttoext_table(struct seq_file *m, void *unused)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
u32 inttoext;
- int i;
+ int ret, i;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
for (i = 1; i <= 32; i++) {
inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
}
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
-static int i915_drpc_info(struct seq_file *m, void *unused)
+static int ironlake_drpc_info(struct seq_file *m)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 rgvmodectl = I915_READ(MEMMODECTL);
- u32 rstdbyctl = I915_READ(RSTDBYCTL);
- u16 crstandvid = I915_READ16(CRSTANDVID);
+ u32 rgvmodectl, rstdbyctl;
+ u16 crstandvid;
+ int ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ rgvmodectl = I915_READ(MEMMODECTL);
+ rstdbyctl = I915_READ(RSTDBYCTL);
+ crstandvid = I915_READ16(CRSTANDVID);
+
+ mutex_unlock(&dev->struct_mutex);
seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ?
"yes" : "no");
@@ -1028,6 +1056,95 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
return 0;
}
+static int gen6_drpc_info(struct seq_file *m)
+{
+
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 rpmodectl1, gt_core_status, rcctl1;
+ unsigned forcewake_count;
+ int count=0, ret;
+
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ spin_lock_irq(&dev_priv->gt_lock);
+ forcewake_count = dev_priv->forcewake_count;
+ spin_unlock_irq(&dev_priv->gt_lock);
+
+ if (forcewake_count) {
+ seq_printf(m, "RC information inaccurate because somebody "
+ "holds a forcewake reference \n");
+ } else {
+ /* NB: we cannot use forcewake, else we read the wrong values */
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
+ udelay(10);
+ seq_printf(m, "RC information accurate: %s\n", yesno(count < 51));
+ }
+
+ gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS);
+ trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4);
+
+ rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
+ rcctl1 = I915_READ(GEN6_RC_CONTROL);
+ mutex_unlock(&dev->struct_mutex);
+
+ seq_printf(m, "Video Turbo Mode: %s\n",
+ yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
+ seq_printf(m, "HW control enabled: %s\n",
+ yesno(rpmodectl1 & GEN6_RP_ENABLE));
+ seq_printf(m, "SW control enabled: %s\n",
+ yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
+ GEN6_RP_MEDIA_SW_MODE));
+ seq_printf(m, "RC1e Enabled: %s\n",
+ yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
+ seq_printf(m, "RC6 Enabled: %s\n",
+ yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
+ seq_printf(m, "Deep RC6 Enabled: %s\n",
+ yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE));
+ seq_printf(m, "Deepest RC6 Enabled: %s\n",
+ yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE));
+ seq_printf(m, "Current RC state: ");
+ switch (gt_core_status & GEN6_RCn_MASK) {
+ case GEN6_RC0:
+ if (gt_core_status & GEN6_CORE_CPD_STATE_MASK)
+ seq_printf(m, "Core Power Down\n");
+ else
+ seq_printf(m, "on\n");
+ break;
+ case GEN6_RC3:
+ seq_printf(m, "RC3\n");
+ break;
+ case GEN6_RC6:
+ seq_printf(m, "RC6\n");
+ break;
+ case GEN6_RC7:
+ seq_printf(m, "RC7\n");
+ break;
+ default:
+ seq_printf(m, "Unknown\n");
+ break;
+ }
+
+ seq_printf(m, "Core Power Down: %s\n",
+ yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
+ return 0;
+}
+
+static int i915_drpc_info(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+
+ if (IS_GEN6(dev) || IS_GEN7(dev))
+ return gen6_drpc_info(m);
+ else
+ return ironlake_drpc_info(m);
+}
+
static int i915_fbc_status(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -1123,14 +1240,59 @@ static int i915_emon_status(struct seq_file *m, void *unused)
return 0;
}
+static int i915_ring_freq_table(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+ int gpu_freq, ia_freq;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
+ seq_printf(m, "unsupported on this chipset\n");
+ return 0;
+ }
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ seq_printf(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\n");
+
+ for (gpu_freq = dev_priv->min_delay; gpu_freq <= dev_priv->max_delay;
+ gpu_freq++) {
+ I915_WRITE(GEN6_PCODE_DATA, gpu_freq);
+ I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY |
+ GEN6_PCODE_READ_MIN_FREQ_TABLE);
+ if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) &
+ GEN6_PCODE_READY) == 0, 10)) {
+ DRM_ERROR("pcode read of freq table timed out\n");
+ continue;
+ }
+ ia_freq = I915_READ(GEN6_PCODE_DATA);
+ seq_printf(m, "%d\t\t%d\n", gpu_freq * 50, ia_freq * 100);
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
static int i915_gfxec(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
@@ -1229,16 +1391,119 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned forcewake_count;
- seq_printf(m, "forcewake count = %d\n",
- atomic_read(&dev_priv->forcewake_count));
+ spin_lock_irq(&dev_priv->gt_lock);
+ forcewake_count = dev_priv->forcewake_count;
+ spin_unlock_irq(&dev_priv->gt_lock);
+
+ seq_printf(m, "forcewake count = %u\n", forcewake_count);
+
+ return 0;
+}
+
+static const char *swizzle_string(unsigned swizzle)
+{
+ switch(swizzle) {
+ case I915_BIT_6_SWIZZLE_NONE:
+ return "none";
+ case I915_BIT_6_SWIZZLE_9:
+ return "bit9";
+ case I915_BIT_6_SWIZZLE_9_10:
+ return "bit9/bit10";
+ case I915_BIT_6_SWIZZLE_9_11:
+ return "bit9/bit11";
+ case I915_BIT_6_SWIZZLE_9_10_11:
+ return "bit9/bit10/bit11";
+ case I915_BIT_6_SWIZZLE_9_17:
+ return "bit9/bit17";
+ case I915_BIT_6_SWIZZLE_9_10_17:
+ return "bit9/bit10/bit17";
+ case I915_BIT_6_SWIZZLE_UNKNOWN:
+ return "unkown";
+ }
+
+ return "bug";
+}
+
+static int i915_swizzle_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev->struct_mutex);
+ seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
+ swizzle_string(dev_priv->mm.bit_6_swizzle_x));
+ seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
+ swizzle_string(dev_priv->mm.bit_6_swizzle_y));
+
+ if (IS_GEN3(dev) || IS_GEN4(dev)) {
+ seq_printf(m, "DDC = 0x%08x\n",
+ I915_READ(DCC));
+ seq_printf(m, "C0DRB3 = 0x%04x\n",
+ I915_READ16(C0DRB3));
+ seq_printf(m, "C1DRB3 = 0x%04x\n",
+ I915_READ16(C1DRB3));
+ } else if (IS_GEN6(dev) || IS_GEN7(dev)) {
+ seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
+ I915_READ(MAD_DIMM_C0));
+ seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
+ I915_READ(MAD_DIMM_C1));
+ seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
+ I915_READ(MAD_DIMM_C2));
+ seq_printf(m, "TILECTL = 0x%08x\n",
+ I915_READ(TILECTL));
+ seq_printf(m, "ARB_MODE = 0x%08x\n",
+ I915_READ(ARB_MODE));
+ seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
+ I915_READ(DISP_ARB_CTL));
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+static int i915_ppgtt_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring;
+ int i, ret;
+
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+ if (INTEL_INFO(dev)->gen == 6)
+ seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));
+
+ for (i = 0; i < I915_NUM_RINGS; i++) {
+ ring = &dev_priv->ring[i];
+
+ seq_printf(m, "%s\n", ring->name);
+ if (INTEL_INFO(dev)->gen == 7)
+ seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
+ seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring)));
+ seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring)));
+ seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring)));
+ }
+ if (dev_priv->mm.aliasing_ppgtt) {
+ struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+ seq_printf(m, "aliasing PPGTT:\n");
+ seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
+ }
+ seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
static int
-i915_wedged_open(struct inode *inode,
- struct file *filp)
+i915_debugfs_common_open(struct inode *inode,
+ struct file *filp)
{
filp->private_data = inode->i_private;
return 0;
@@ -1255,12 +1520,12 @@ i915_wedged_read(struct file *filp,
char buf[80];
int len;
- len = snprintf(buf, sizeof (buf),
+ len = snprintf(buf, sizeof(buf),
"wedged : %d\n",
atomic_read(&dev_priv->mm.wedged));
- if (len > sizeof (buf))
- len = sizeof (buf);
+ if (len > sizeof(buf))
+ len = sizeof(buf);
return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
@@ -1276,7 +1541,7 @@ i915_wedged_write(struct file *filp,
int val = 1;
if (cnt > 0) {
- if (cnt > sizeof (buf) - 1)
+ if (cnt > sizeof(buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, cnt))
@@ -1294,12 +1559,145 @@ i915_wedged_write(struct file *filp,
static const struct file_operations i915_wedged_fops = {
.owner = THIS_MODULE,
- .open = i915_wedged_open,
+ .open = i915_debugfs_common_open,
.read = i915_wedged_read,
.write = i915_wedged_write,
.llseek = default_llseek,
};
+static ssize_t
+i915_max_freq_read(struct file *filp,
+ char __user *ubuf,
+ size_t max,
+ loff_t *ppos)
+{
+ struct drm_device *dev = filp->private_data;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ char buf[80];
+ int len;
+
+ len = snprintf(buf, sizeof(buf),
+ "max freq: %d\n", dev_priv->max_delay * 50);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(ubuf, max, ppos, buf, len);
+}
+
+static ssize_t
+i915_max_freq_write(struct file *filp,
+ const char __user *ubuf,
+ size_t cnt,
+ loff_t *ppos)
+{
+ struct drm_device *dev = filp->private_data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ char buf[20];
+ int val = 1;
+
+ if (cnt > 0) {
+ if (cnt > sizeof(buf) - 1)
+ return -EINVAL;
+
+ if (copy_from_user(buf, ubuf, cnt))
+ return -EFAULT;
+ buf[cnt] = 0;
+
+ val = simple_strtoul(buf, NULL, 0);
+ }
+
+ DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val);
+
+ /*
+ * Turbo will still be enabled, but won't go above the set value.
+ */
+ dev_priv->max_delay = val / 50;
+
+ gen6_set_rps(dev, val / 50);
+
+ return cnt;
+}
+
+static const struct file_operations i915_max_freq_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_debugfs_common_open,
+ .read = i915_max_freq_read,
+ .write = i915_max_freq_write,
+ .llseek = default_llseek,
+};
+
+static ssize_t
+i915_cache_sharing_read(struct file *filp,
+ char __user *ubuf,
+ size_t max,
+ loff_t *ppos)
+{
+ struct drm_device *dev = filp->private_data;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ char buf[80];
+ u32 snpcr;
+ int len;
+
+ mutex_lock(&dev_priv->dev->struct_mutex);
+ snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+ mutex_unlock(&dev_priv->dev->struct_mutex);
+
+ len = snprintf(buf, sizeof(buf),
+ "%d\n", (snpcr & GEN6_MBC_SNPCR_MASK) >>
+ GEN6_MBC_SNPCR_SHIFT);
+
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+
+ return simple_read_from_buffer(ubuf, max, ppos, buf, len);
+}
+
+static ssize_t
+i915_cache_sharing_write(struct file *filp,
+ const char __user *ubuf,
+ size_t cnt,
+ loff_t *ppos)
+{
+ struct drm_device *dev = filp->private_data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ char buf[20];
+ u32 snpcr;
+ int val = 1;
+
+ if (cnt > 0) {
+ if (cnt > sizeof(buf) - 1)
+ return -EINVAL;
+
+ if (copy_from_user(buf, ubuf, cnt))
+ return -EFAULT;
+ buf[cnt] = 0;
+
+ val = simple_strtoul(buf, NULL, 0);
+ }
+
+ if (val < 0 || val > 3)
+ return -EINVAL;
+
+ DRM_DEBUG_DRIVER("Manually setting uncore sharing to %d\n", val);
+
+ /* Update the cache sharing policy here as well */
+ snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+ snpcr &= ~GEN6_MBC_SNPCR_MASK;
+ snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
+ I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
+
+ return cnt;
+}
+
+static const struct file_operations i915_cache_sharing_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_debugfs_common_open,
+ .read = i915_cache_sharing_read,
+ .write = i915_cache_sharing_write,
+ .llseek = default_llseek,
+};
+
/* As the drm_debugfs_init() routines are called before dev->dev_private is
* allocated we need to hook into the minor for release. */
static int
@@ -1318,24 +1716,12 @@ drm_add_fake_info_node(struct drm_minor *minor,
node->minor = minor;
node->dent = ent;
node->info_ent = (void *) key;
- list_add(&node->list, &minor->debugfs_nodes.list);
-
- return 0;
-}
-
-static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
-{
- struct drm_device *dev = minor->dev;
- struct dentry *ent;
- ent = debugfs_create_file("i915_wedged",
- S_IRUGO | S_IWUSR,
- root, dev,
- &i915_wedged_fops);
- if (IS_ERR(ent))
- return PTR_ERR(ent);
+ mutex_lock(&minor->debugfs_lock);
+ list_add(&node->list, &minor->debugfs_list);
+ mutex_unlock(&minor->debugfs_lock);
- return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
+ return 0;
}
static int i915_forcewake_open(struct inode *inode, struct file *file)
@@ -1344,7 +1730,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- if (!IS_GEN6(dev))
+ if (INTEL_INFO(dev)->gen < 6)
return 0;
ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -1361,7 +1747,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file)
struct drm_device *dev = inode->i_private;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!IS_GEN6(dev))
+ if (INTEL_INFO(dev)->gen < 6)
return 0;
/*
@@ -1399,6 +1785,24 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
}
+static int i915_debugfs_create(struct dentry *root,
+ struct drm_minor *minor,
+ const char *name,
+ const struct file_operations *fops)
+{
+ struct drm_device *dev = minor->dev;
+ struct dentry *ent;
+
+ ent = debugfs_create_file(name,
+ S_IRUGO | S_IWUSR,
+ root, dev,
+ fops);
+ if (IS_ERR(ent))
+ return PTR_ERR(ent);
+
+ return drm_add_fake_info_node(minor, ent, fops);
+}
+
static struct drm_info_list i915_debugfs_list[] = {
{"i915_capabilities", i915_capabilities, 0},
{"i915_gem_objects", i915_gem_object_info, 0},
@@ -1422,7 +1826,6 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS},
{"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS},
{"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS},
- {"i915_batchbuffers", i915_batchbuffer_info, 0},
{"i915_error_state", i915_error_state, 0},
{"i915_rstdby_delays", i915_rstdby_delays, 0},
{"i915_cur_delayinfo", i915_cur_delayinfo, 0},
@@ -1430,6 +1833,7 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_inttoext_table", i915_inttoext_table, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
+ {"i915_ring_freq_table", i915_ring_freq_table, 0},
{"i915_gfxec", i915_gfxec, 0},
{"i915_fbc_status", i915_fbc_status, 0},
{"i915_sr_status", i915_sr_status, 0},
@@ -1437,6 +1841,8 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
{"i915_context_status", i915_context_status, 0},
{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
+ {"i915_swizzle_info", i915_swizzle_info, 0},
+ {"i915_ppgtt_info", i915_ppgtt_info, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
@@ -1444,7 +1850,9 @@ int i915_debugfs_init(struct drm_minor *minor)
{
int ret;
- ret = i915_wedged_create(minor->debugfs_root, minor);
+ ret = i915_debugfs_create(minor->debugfs_root, minor,
+ "i915_wedged",
+ &i915_wedged_fops);
if (ret)
return ret;
@@ -1452,6 +1860,18 @@ int i915_debugfs_init(struct drm_minor *minor)
if (ret)
return ret;
+ ret = i915_debugfs_create(minor->debugfs_root, minor,
+ "i915_max_freq",
+ &i915_max_freq_fops);
+ if (ret)
+ return ret;
+
+ ret = i915_debugfs_create(minor->debugfs_root, minor,
+ "i915_cache_sharing",
+ &i915_cache_sharing_fops);
+ if (ret)
+ return ret;
+
return drm_debugfs_create_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES,
minor->debugfs_root, minor);
@@ -1465,6 +1885,10 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
1, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
1, minor);
+ drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops,
+ 1, minor);
+ drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops,
+ 1, minor);
}
#endif /* CONFIG_DEBUG_FS */
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_dma.c smdk4210/drivers/gpu/drm/i915/i915_dma.c
index ef16443..9341eb8 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_dma.c
+++ smdk4210/drivers/gpu/drm/i915/i915_dma.c
@@ -41,6 +41,7 @@
#include <linux/pnp.h>
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
+#include <linux/module.h>
#include <acpi/video.h>
static void i915_write_hws_pga(struct drm_device *dev)
@@ -780,6 +781,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_RELAXED_DELTA:
value = 1;
break;
+ case I915_PARAM_HAS_GEN7_SOL_RESET:
+ value = 1;
+ break;
+ case I915_PARAM_HAS_LLC:
+ value = HAS_LLC(dev);
+ break;
default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param);
@@ -884,7 +891,7 @@ static int i915_get_bridge_dev(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+ dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
if (!dev_priv->bridge_dev) {
DRM_ERROR("bridge device not found\n");
return -1;
@@ -1071,6 +1078,9 @@ static void i915_setup_compression(struct drm_device *dev, int size)
unsigned long cfb_base;
unsigned long ll_base = 0;
+ /* Just in case the BIOS is doing something questionable. */
+ intel_disable_fbc(dev);
+
compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0);
if (compressed_fb)
compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
@@ -1097,7 +1107,6 @@ static void i915_setup_compression(struct drm_device *dev, int size)
dev_priv->cfb_size = size;
- intel_disable_fbc(dev);
dev_priv->compressed_fb = compressed_fb;
if (HAS_PCH_SPLIT(dev))
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
@@ -1187,22 +1196,39 @@ static int i915_load_gem_init(struct drm_device *dev)
/* Basic memrange allocator for stolen space */
drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size);
- /* Let GEM Manage all of the aperture.
- *
- * However, leave one page at the end still bound to the scratch page.
- * There are a number of places where the hardware apparently
- * prefetches past the end of the object, and we've seen multiple
- * hangs with the GPU head pointer stuck in a batchbuffer bound
- * at the last page of the aperture. One page should be enough to
- * keep any prefetching inside of the aperture.
- */
- i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE);
-
mutex_lock(&dev->struct_mutex);
- ret = i915_gem_init_ringbuffer(dev);
+ if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) {
+ /* PPGTT pdes are stolen from global gtt ptes, so shrink the
+ * aperture accordingly when using aliasing ppgtt. */
+ gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
+ /* For paranoia keep the guard page in between. */
+ gtt_size -= PAGE_SIZE;
+
+ i915_gem_do_init(dev, 0, mappable_size, gtt_size);
+
+ ret = i915_gem_init_aliasing_ppgtt(dev);
+ if (ret)
+ return ret;
+ } else {
+ /* Let GEM Manage all of the aperture.
+ *
+ * However, leave one page at the end still bound to the scratch
+ * page. There are a number of places where the hardware
+ * apparently prefetches past the end of the object, and we've
+ * seen multiple hangs with the GPU head pointer stuck in a
+ * batchbuffer bound at the last page of the aperture. One page
+ * should be enough to keep any prefetching inside of the
+ * aperture.
+ */
+ i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE);
+ }
+
+ ret = i915_gem_init_hw(dev);
mutex_unlock(&dev->struct_mutex);
- if (ret)
+ if (ret) {
+ i915_gem_cleanup_aliasing_ppgtt(dev);
return ret;
+ }
/* Try to set up FBC with a reasonable compressed buffer size */
if (I915_HAS_FBC(dev) && i915_powersave) {
@@ -1289,6 +1315,7 @@ cleanup_gem:
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
+ i915_gem_cleanup_aliasing_ppgtt(dev);
cleanup_vga_switcheroo:
vga_switcheroo_unregister_client(dev->pdev);
cleanup_vga_client:
@@ -1738,10 +1765,10 @@ static DEFINE_SPINLOCK(mchdev_lock);
*/
unsigned long i915_read_mch_val(void)
{
- struct drm_i915_private *dev_priv;
+ struct drm_i915_private *dev_priv;
unsigned long chipset_val, graphics_val, ret = 0;
- spin_lock(&mchdev_lock);
+ spin_lock(&mchdev_lock);
if (!i915_mch_dev)
goto out_unlock;
dev_priv = i915_mch_dev;
@@ -1752,9 +1779,9 @@ unsigned long i915_read_mch_val(void)
ret = chipset_val + graphics_val;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock(&mchdev_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(i915_read_mch_val);
@@ -1765,10 +1792,10 @@ EXPORT_SYMBOL_GPL(i915_read_mch_val);
*/
bool i915_gpu_raise(void)
{
- struct drm_i915_private *dev_priv;
+ struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
@@ -1779,9 +1806,9 @@ bool i915_gpu_raise(void)
dev_priv->max_delay--;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock(&mchdev_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(i915_gpu_raise);
@@ -1793,10 +1820,10 @@ EXPORT_SYMBOL_GPL(i915_gpu_raise);
*/
bool i915_gpu_lower(void)
{
- struct drm_i915_private *dev_priv;
+ struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
@@ -1807,9 +1834,9 @@ bool i915_gpu_lower(void)
dev_priv->max_delay++;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock(&mchdev_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(i915_gpu_lower);
@@ -1820,10 +1847,10 @@ EXPORT_SYMBOL_GPL(i915_gpu_lower);
*/
bool i915_gpu_busy(void)
{
- struct drm_i915_private *dev_priv;
+ struct drm_i915_private *dev_priv;
bool ret = false;
- spin_lock(&mchdev_lock);
+ spin_lock(&mchdev_lock);
if (!i915_mch_dev)
goto out_unlock;
dev_priv = i915_mch_dev;
@@ -1831,9 +1858,9 @@ bool i915_gpu_busy(void)
ret = dev_priv->busy;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock(&mchdev_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(i915_gpu_busy);
@@ -1845,10 +1872,10 @@ EXPORT_SYMBOL_GPL(i915_gpu_busy);
*/
bool i915_gpu_turbo_disable(void)
{
- struct drm_i915_private *dev_priv;
+ struct drm_i915_private *dev_priv;
bool ret = true;
- spin_lock(&mchdev_lock);
+ spin_lock(&mchdev_lock);
if (!i915_mch_dev) {
ret = false;
goto out_unlock;
@@ -1861,9 +1888,9 @@ bool i915_gpu_turbo_disable(void)
ret = false;
out_unlock:
- spin_unlock(&mchdev_lock);
+ spin_unlock(&mchdev_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
@@ -1924,6 +1951,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
+ pci_set_master(dev->pdev);
+
/* overlay on gen2 is broken and can't address above 1G */
if (IS_GEN2(dev))
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
@@ -1956,7 +1985,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
- dev_priv->mm.gtt_mapping =
+ dev_priv->mm.gtt_mapping =
io_mapping_create_wc(dev->agp->base, agp_size);
if (dev_priv->mm.gtt_mapping == NULL) {
ret = -EIO;
@@ -2039,11 +2068,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
+ spin_lock_init(&dev_priv->gt_lock);
spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->error_lock);
spin_lock_init(&dev_priv->rps_lock);
- if (IS_MOBILE(dev) || !IS_GEN2(dev))
+ if (IS_IVYBRIDGE(dev))
+ dev_priv->num_pipe = 3;
+ else if (IS_MOBILE(dev) || !IS_GEN2(dev))
dev_priv->num_pipe = 2;
else
dev_priv->num_pipe = 1;
@@ -2120,7 +2152,7 @@ int i915_driver_unload(struct drm_device *dev)
unregister_shrinker(&dev_priv->mm.inactive_shrinker);
mutex_lock(&dev->struct_mutex);
- ret = i915_gpu_idle(dev);
+ ret = i915_gpu_idle(dev, true);
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
mutex_unlock(&dev->struct_mutex);
@@ -2173,6 +2205,7 @@ int i915_driver_unload(struct drm_device *dev)
i915_gem_free_all_phys_object(dev);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
+ i915_gem_cleanup_aliasing_ppgtt(dev);
if (I915_HAS_FBC(dev) && i915_powersave)
i915_cleanup_compression(dev);
drm_mm_takedown(&dev_priv->mm.stolen);
@@ -2238,18 +2271,12 @@ void i915_driver_lastclose(struct drm_device * dev)
i915_gem_lastclose(dev);
- if (dev_priv->agp_heap)
- i915_mem_takedown(&(dev_priv->agp_heap));
-
i915_dma_cleanup(dev);
}
void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
i915_gem_release(dev, file_priv);
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
- i915_mem_release(dev, file_priv, dev_priv->agp_heap);
}
void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
@@ -2268,11 +2295,11 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH),
DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
- DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH),
DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
@@ -2300,6 +2327,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_drv.c smdk4210/drivers/gpu/drm/i915/i915_drv.c
index 111686a..2b8c1f2 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_drv.c
+++ smdk4210/drivers/gpu/drm/i915/i915_drv.c
@@ -35,46 +35,84 @@
#include "intel_drv.h"
#include <linux/console.h>
+#include <linux/module.h>
#include "drm_crtc_helper.h"
-static int i915_modeset = -1;
+static int i915_modeset __read_mostly = -1;
module_param_named(modeset, i915_modeset, int, 0400);
+MODULE_PARM_DESC(modeset,
+ "Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, "
+ "1=on, -1=force vga console preference [default])");
-unsigned int i915_fbpercrtc = 0;
+unsigned int i915_fbpercrtc __always_unused = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
-int i915_panel_ignore_lid = 0;
+int i915_panel_ignore_lid __read_mostly = 0;
module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600);
+MODULE_PARM_DESC(panel_ignore_lid,
+ "Override lid status (0=autodetect [default], 1=lid open, "
+ "-1=lid closed)");
-unsigned int i915_powersave = 1;
+unsigned int i915_powersave __read_mostly = 1;
module_param_named(powersave, i915_powersave, int, 0600);
+MODULE_PARM_DESC(powersave,
+ "Enable powersavings, fbc, downclocking, etc. (default: true)");
-unsigned int i915_semaphores = 0;
+int i915_semaphores __read_mostly = -1;
module_param_named(semaphores, i915_semaphores, int, 0600);
+MODULE_PARM_DESC(semaphores,
+ "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
-unsigned int i915_enable_rc6 = 0;
+int i915_enable_rc6 __read_mostly = -1;
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+MODULE_PARM_DESC(i915_enable_rc6,
+ "Enable power-saving render C-state 6 (default: -1 (use per-chip default)");
-unsigned int i915_enable_fbc = 0;
+int i915_enable_fbc __read_mostly = -1;
module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
+MODULE_PARM_DESC(i915_enable_fbc,
+ "Enable frame buffer compression for power savings "
+ "(default: -1 (use per-chip default))");
-unsigned int i915_lvds_downclock = 0;
+unsigned int i915_lvds_downclock __read_mostly = 0;
module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
+MODULE_PARM_DESC(lvds_downclock,
+ "Use panel (LVDS/eDP) downclocking for power savings "
+ "(default: false)");
-unsigned int i915_panel_use_ssc = 1;
+int i915_panel_use_ssc __read_mostly = -1;
module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600);
+MODULE_PARM_DESC(lvds_use_ssc,
+ "Use Spread Spectrum Clock with panels [LVDS/eDP] "
+ "(default: auto from VBT)");
-int i915_vbt_sdvo_panel_type = -1;
+int i915_vbt_sdvo_panel_type __read_mostly = -1;
module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600);
+MODULE_PARM_DESC(vbt_sdvo_panel_type,
+ "Override selection of SDVO panel mode in the VBT "
+ "(default: auto)");
-static bool i915_try_reset = true;
+static bool i915_try_reset __read_mostly = true;
module_param_named(reset, i915_try_reset, bool, 0600);
+MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
+
+bool i915_enable_hangcheck __read_mostly = true;
+module_param_named(enable_hangcheck, i915_enable_hangcheck, bool, 0644);
+MODULE_PARM_DESC(enable_hangcheck,
+ "Periodically check GPU activity for detecting hangs. "
+ "WARNING: Disabling this can cause system wide hangs. "
+ "(default: true)");
+
+bool i915_enable_ppgtt __read_mostly = 1;
+module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600);
+MODULE_PARM_DESC(i915_enable_ppgtt,
+ "Enable PPGTT (default: true)");
static struct drm_driver driver;
extern int intel_agp_enabled;
#define INTEL_VGA_DEVICE(id, info) { \
- .class = PCI_CLASS_DISPLAY_VGA << 8, \
+ .class = PCI_BASE_CLASS_DISPLAY << 16, \
.class_mask = 0xff0000, \
.vendor = 0x8086, \
.device = id, \
@@ -165,7 +203,7 @@ static const struct intel_device_info intel_pineview_info = {
static const struct intel_device_info intel_ironlake_d_info = {
.gen = 5,
- .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
+ .need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1,
};
@@ -181,6 +219,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1,
.has_blt_ring = 1,
+ .has_llc = 1,
};
static const struct intel_device_info intel_sandybridge_m_info = {
@@ -189,6 +228,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
.has_fbc = 1,
.has_bsd_ring = 1,
.has_blt_ring = 1,
+ .has_llc = 1,
};
static const struct intel_device_info intel_ivybridge_d_info = {
@@ -196,6 +236,7 @@ static const struct intel_device_info intel_ivybridge_d_info = {
.need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1,
.has_blt_ring = 1,
+ .has_llc = 1,
};
static const struct intel_device_info intel_ivybridge_m_info = {
@@ -204,6 +245,7 @@ static const struct intel_device_info intel_ivybridge_m_info = {
.has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */
.has_bsd_ring = 1,
.has_blt_ring = 1,
+ .has_llc = 1,
};
static const struct pci_device_id pciidlist[] = { /* aka */
@@ -262,7 +304,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
-void intel_detect_pch (struct drm_device *dev)
+void intel_detect_pch(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct pci_dev *pch;
@@ -295,7 +337,7 @@ void intel_detect_pch (struct drm_device *dev)
}
}
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
@@ -311,6 +353,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
udelay(10);
}
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+ int count;
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+ udelay(10);
+
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
+ POSTING_READ(FORCEWAKE_MT);
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+ udelay(10);
+}
+
/*
* Generally this is called implicitly by the register read function. However,
* if some sequence requires the GT to not power down then this function should
@@ -319,17 +377,35 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+ if (dev_priv->forcewake_count++ == 0)
+ dev_priv->display.force_wake_get(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
+}
- /* Forcewake is atomic in case we get in here without the lock */
- if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
- __gen6_gt_force_wake_get(dev_priv);
+static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
+{
+ u32 gtfifodbg;
+ gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
+ if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK,
+ "MMIO read or write has been dropped %x\n", gtfifodbg))
+ I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
}
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
- POSTING_READ(FORCEWAKE);
+ /* The below doubles as a POSTING_READ */
+ gen6_gt_check_fifodbg(dev_priv);
+}
+
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
+ /* The below doubles as a POSTING_READ */
+ gen6_gt_check_fifodbg(dev_priv);
}
/*
@@ -337,20 +413,32 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+ unsigned long irqflags;
- if (atomic_dec_and_test(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_put(dev_priv);
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+ if (--dev_priv->forcewake_count == 0)
+ dev_priv->display.force_wake_put(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}
-void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
+int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
{
- int loop = 500;
- u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
- while (fifo < 20 && loop--) {
- udelay(10);
- fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
+ int ret = 0;
+
+ if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
+ int loop = 500;
+ u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
+ while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
+ udelay(10);
+ fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
+ }
+ if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
+ ++ret;
+ dev_priv->gt_fifo_count = fifo;
}
+ dev_priv->gt_fifo_count--;
+
+ return ret;
}
static int i915_drm_freeze(struct drm_device *dev)
@@ -435,9 +523,12 @@ static int i915_drm_thaw(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;
- error = i915_gem_init_ringbuffer(dev);
+ error = i915_gem_init_hw(dev);
mutex_unlock(&dev->struct_mutex);
+ if (HAS_PCH_SPLIT(dev))
+ ironlake_init_pch_refclk(dev);
+
drm_mode_config_reset(dev);
drm_irq_install(dev);
@@ -543,13 +634,40 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags)
static int gen6_do_reset(struct drm_device *dev, u8 flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+ unsigned long irqflags;
+
+ /* Hold gt_lock across reset to prevent any register access
+ * with forcewake not set correctly
+ */
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+
+ /* Reset the chip */
+
+ /* GEN6_GDRST is not in the gt power well, no need to check
+ * for fifo space for the write or forcewake the chip for
+ * the read
+ */
+ I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
+
+ /* Spin waiting for the device to ack the reset request */
+ ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
+
+ /* If reset with a user forcewake, try to restore, otherwise turn it off */
+ if (dev_priv->forcewake_count)
+ dev_priv->display.force_wake_get(dev_priv);
+ else
+ dev_priv->display.force_wake_put(dev_priv);
- I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL);
- return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
+ /* Restore fifo count */
+ dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
+
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
+ return ret;
}
/**
- * i965_reset - reset chip after a hang
+ * i915_reset - reset chip after a hang
* @dev: drm device to reset
* @flags: reset domains
*
@@ -589,9 +707,6 @@ int i915_reset(struct drm_device *dev, u8 flags)
case 7:
case 6:
ret = gen6_do_reset(dev, flags);
- /* If reset with a user forcewake, try to restore */
- if (atomic_read(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_get(dev_priv);
break;
case 5:
ret = ironlake_do_reset(dev, flags);
@@ -628,12 +743,16 @@ int i915_reset(struct drm_device *dev, u8 flags)
!dev_priv->mm.suspended) {
dev_priv->mm.suspended = 0;
+ i915_gem_init_swizzling(dev);
+
dev_priv->ring[RCS].init(&dev_priv->ring[RCS]);
if (HAS_BSD(dev))
dev_priv->ring[VCS].init(&dev_priv->ring[VCS]);
if (HAS_BLT(dev))
dev_priv->ring[BCS].init(&dev_priv->ring[BCS]);
+ i915_gem_init_ppgtt(dev);
+
mutex_unlock(&dev->struct_mutex);
drm_irq_uninstall(dev);
drm_mode_config_reset(dev);
@@ -742,12 +861,12 @@ static int i915_pm_poweroff(struct device *dev)
}
static const struct dev_pm_ops i915_pm_ops = {
- .suspend = i915_pm_suspend,
- .resume = i915_pm_resume,
- .freeze = i915_pm_freeze,
- .thaw = i915_pm_thaw,
- .poweroff = i915_pm_poweroff,
- .restore = i915_pm_resume,
+ .suspend = i915_pm_suspend,
+ .resume = i915_pm_resume,
+ .freeze = i915_pm_freeze,
+ .thaw = i915_pm_thaw,
+ .poweroff = i915_pm_poweroff,
+ .restore = i915_pm_resume,
};
static struct vm_operations_struct i915_gem_vm_ops = {
@@ -756,9 +875,24 @@ static struct vm_operations_struct i915_gem_vm_ops = {
.close = drm_gem_vm_close,
};
+static const struct file_operations i915_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = drm_gem_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ .read = drm_read,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = i915_compat_ioctl,
+#endif
+ .llseek = noop_llseek,
+};
+
static struct drm_driver driver = {
- /* don't use mtrr's here, the Xserver or user space app should
- * deal with them for intel hardware.
+ /* Don't use MTRRs here; the Xserver or userspace app should
+ * deal with them for Intel hardware.
*/
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
@@ -789,21 +923,7 @@ static struct drm_driver driver = {
.dumb_map_offset = i915_gem_mmap_gtt,
.dumb_destroy = i915_gem_dumb_destroy,
.ioctls = i915_ioctls,
- .fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .mmap = drm_gem_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- .read = drm_read,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = i915_compat_ioctl,
-#endif
- .llseek = noop_llseek,
- },
-
+ .fops = &i915_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
@@ -867,3 +987,46 @@ module_exit(i915_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
+
+#define __i915_read(x, y) \
+u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
+ u##x val = 0; \
+ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+ unsigned long irqflags; \
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
+ if (dev_priv->forcewake_count == 0) \
+ dev_priv->display.force_wake_get(dev_priv); \
+ val = read##y(dev_priv->regs + reg); \
+ if (dev_priv->forcewake_count == 0) \
+ dev_priv->display.force_wake_put(dev_priv); \
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
+ } else { \
+ val = read##y(dev_priv->regs + reg); \
+ } \
+ trace_i915_reg_rw(false, reg, val, sizeof(val)); \
+ return val; \
+}
+
+__i915_read(8, b)
+__i915_read(16, w)
+__i915_read(32, l)
+__i915_read(64, q)
+#undef __i915_read
+
+#define __i915_write(x, y) \
+void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
+ u32 __fifo_ret = 0; \
+ trace_i915_reg_rw(true, reg, val, sizeof(val)); \
+ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
+ } \
+ write##y(val, dev_priv->regs + reg); \
+ if (unlikely(__fifo_ret)) { \
+ gen6_gt_check_fifodbg(dev_priv); \
+ } \
+}
+__i915_write(8, b)
+__i915_write(16, w)
+__i915_write(32, l)
+__i915_write(64, q)
+#undef __i915_write
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_drv.h smdk4210/drivers/gpu/drm/i915/i915_drv.h
index b570415..c0f19f5 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_drv.h
+++ smdk4210/drivers/gpu/drm/i915/i915_drv.h
@@ -35,7 +35,9 @@
#include "intel_ringbuffer.h"
#include <linux/io-mapping.h>
#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
#include <drm/intel-gtt.h>
+#include <linux/backlight.h>
/* General customization:
*/
@@ -106,6 +108,7 @@ struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
+struct drm_i915_private;
struct intel_opregion {
struct opregion_header *header;
@@ -125,11 +128,15 @@ struct drm_i915_master_private {
struct _drm_i915_sarea *sarea_priv;
};
#define I915_FENCE_REG_NONE -1
+#define I915_MAX_NUM_FENCES 16
+/* 16 fences + sign bit for FENCE_REG_NONE */
+#define I915_MAX_NUM_FENCE_BITS 5
struct drm_i915_fence_reg {
struct list_head lru_list;
struct drm_i915_gem_object *obj;
uint32_t setup_seqno;
+ int pin_count;
};
struct sdvo_device_mapping {
@@ -138,7 +145,6 @@ struct sdvo_device_mapping {
u8 slave_addr;
u8 dvo_wiring;
u8 i2c_pin;
- u8 i2c_speed;
u8 ddc_pin;
};
@@ -148,33 +154,40 @@ struct drm_i915_error_state {
u32 eir;
u32 pgtbl_er;
u32 pipestat[I915_MAX_PIPES];
- u32 ipeir;
- u32 ipehr;
- u32 instdone;
- u32 acthd;
+ u32 tail[I915_NUM_RINGS];
+ u32 head[I915_NUM_RINGS];
+ u32 ipeir[I915_NUM_RINGS];
+ u32 ipehr[I915_NUM_RINGS];
+ u32 instdone[I915_NUM_RINGS];
+ u32 acthd[I915_NUM_RINGS];
+ u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1];
+ /* our own tracking of ring head and tail */
+ u32 cpu_ring_head[I915_NUM_RINGS];
+ u32 cpu_ring_tail[I915_NUM_RINGS];
u32 error; /* gen6+ */
- u32 bcs_acthd; /* gen6+ blt engine */
- u32 bcs_ipehr;
- u32 bcs_ipeir;
- u32 bcs_instdone;
- u32 bcs_seqno;
- u32 vcs_acthd; /* gen6+ bsd engine */
- u32 vcs_ipehr;
- u32 vcs_ipeir;
- u32 vcs_instdone;
- u32 vcs_seqno;
- u32 instpm;
- u32 instps;
+ u32 instpm[I915_NUM_RINGS];
+ u32 instps[I915_NUM_RINGS];
u32 instdone1;
- u32 seqno;
+ u32 seqno[I915_NUM_RINGS];
u64 bbaddr;
- u64 fence[16];
+ u32 fault_reg[I915_NUM_RINGS];
+ u32 done_reg;
+ u32 faddr[I915_NUM_RINGS];
+ u64 fence[I915_MAX_NUM_FENCES];
struct timeval time;
- struct drm_i915_error_object {
- int page_count;
- u32 gtt_offset;
- u32 *pages[0];
- } *ringbuffer[I915_NUM_RINGS], *batchbuffer[I915_NUM_RINGS];
+ struct drm_i915_error_ring {
+ struct drm_i915_error_object {
+ int page_count;
+ u32 gtt_offset;
+ u32 *pages[0];
+ } *ringbuffer, *batchbuffer;
+ struct drm_i915_error_request {
+ long jiffies;
+ u32 seqno;
+ u32 tail;
+ } *requests;
+ int num_requests;
+ } ring[I915_NUM_RINGS];
struct drm_i915_error_buffer {
u32 size;
u32 name;
@@ -182,12 +195,12 @@ struct drm_i915_error_state {
u32 gtt_offset;
u32 read_domains;
u32 write_domain;
- s32 fence_reg:5;
+ s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
s32 pinned:2;
u32 tiling:2;
u32 dirty:1;
u32 purgeable:1;
- u32 ring:4;
+ s32 ring:4;
u32 cache_level:2;
} *active_bo, *pinned_bo;
u32 active_bo_count, pinned_bo_count;
@@ -203,17 +216,25 @@ struct drm_i915_display_funcs {
int (*get_display_clock_speed)(struct drm_device *dev);
int (*get_fifo_size)(struct drm_device *dev, int plane);
void (*update_wm)(struct drm_device *dev);
+ void (*update_sprite_wm)(struct drm_device *dev, int pipe,
+ uint32_t sprite_width, int pixel_size);
int (*crtc_mode_set)(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y,
struct drm_framebuffer *old_fb);
+ void (*write_eld)(struct drm_connector *connector,
+ struct drm_crtc *crtc);
void (*fdi_link_train)(struct drm_crtc *crtc);
void (*init_clock_gating)(struct drm_device *dev);
void (*init_pch_clock_gating)(struct drm_device *dev);
int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj);
+ int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
+ int x, int y);
+ void (*force_wake_get)(struct drm_i915_private *dev_priv);
+ void (*force_wake_put)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -223,26 +244,37 @@ struct drm_i915_display_funcs {
struct intel_device_info {
u8 gen;
- u8 is_mobile : 1;
- u8 is_i85x : 1;
- u8 is_i915g : 1;
- u8 is_i945gm : 1;
- u8 is_g33 : 1;
- u8 need_gfx_hws : 1;
- u8 is_g4x : 1;
- u8 is_pineview : 1;
- u8 is_broadwater : 1;
- u8 is_crestline : 1;
- u8 is_ivybridge : 1;
- u8 has_fbc : 1;
- u8 has_pipe_cxsr : 1;
- u8 has_hotplug : 1;
- u8 cursor_needs_physical : 1;
- u8 has_overlay : 1;
- u8 overlay_needs_physical : 1;
- u8 supports_tv : 1;
- u8 has_bsd_ring : 1;
- u8 has_blt_ring : 1;
+ u8 is_mobile:1;
+ u8 is_i85x:1;
+ u8 is_i915g:1;
+ u8 is_i945gm:1;
+ u8 is_g33:1;
+ u8 need_gfx_hws:1;
+ u8 is_g4x:1;
+ u8 is_pineview:1;
+ u8 is_broadwater:1;
+ u8 is_crestline:1;
+ u8 is_ivybridge:1;
+ u8 has_fbc:1;
+ u8 has_pipe_cxsr:1;
+ u8 has_hotplug:1;
+ u8 cursor_needs_physical:1;
+ u8 has_overlay:1;
+ u8 overlay_needs_physical:1;
+ u8 supports_tv:1;
+ u8 has_bsd_ring:1;
+ u8 has_blt_ring:1;
+ u8 has_llc:1;
+};
+
+#define I915_PPGTT_PD_ENTRIES 512
+#define I915_PPGTT_PT_ENTRIES 1024
+struct i915_hw_ppgtt {
+ unsigned num_pd_entries;
+ struct page **pt_pages;
+ uint32_t pd_offset;
+ dma_addr_t *pt_dma_addr;
+ dma_addr_t scratch_page_dma_addr;
};
enum no_fbc_reason {
@@ -265,6 +297,17 @@ enum intel_pch {
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
struct intel_fbdev;
+struct intel_fbc_work;
+
+struct intel_gmbus {
+ struct i2c_adapter adapter;
+ bool force_bit;
+ bool has_gpio;
+ u32 reg0;
+ u32 gpio_reg;
+ struct i2c_algo_bit_data bit_algo;
+ struct drm_i915_private *dev_priv;
+};
typedef struct drm_i915_private {
struct drm_device *dev;
@@ -275,12 +318,19 @@ typedef struct drm_i915_private {
int relative_constants_mode;
void __iomem *regs;
+ /** gt_fifo_count and the subsequent register write are synchronized
+ * with dev->struct_mutex. */
+ unsigned gt_fifo_count;
+ /** forcewake_count is protected by gt_lock */
+ unsigned forcewake_count;
+ /** gt_lock is also taken in irq contexts. */
+ struct spinlock gt_lock;
+
+ struct intel_gmbus *gmbus;
- struct intel_gmbus {
- struct i2c_adapter adapter;
- struct i2c_adapter *force_bit;
- u32 reg0;
- } *gmbus;
+ /** gmbus_mutex protects against concurrent usage of the single hw gmbus
+ * controller on different i2c buses. */
+ struct mutex gmbus_mutex;
struct pci_dev *bridge_dev;
struct intel_ring_buffer ring[I915_NUM_RINGS];
@@ -315,7 +365,6 @@ typedef struct drm_i915_private {
int tex_lru_log_granularity;
int allow_batchbuffer;
- struct mem_block *agp_heap;
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
int vblank_pipe;
int num_pipe;
@@ -331,21 +380,20 @@ typedef struct drm_i915_private {
uint32_t last_instdone1;
unsigned long cfb_size;
- unsigned long cfb_pitch;
- unsigned long cfb_offset;
- int cfb_fence;
- int cfb_plane;
+ unsigned int cfb_fb;
+ enum plane cfb_plane;
int cfb_y;
+ struct intel_fbc_work *fbc_work;
struct intel_opregion opregion;
/* overlay */
struct intel_overlay *overlay;
+ bool sprite_scaling_enabled;
/* LVDS info */
int backlight_level; /* restore backlight to this value */
bool backlight_enabled;
- struct drm_display_mode *panel_fixed_mode;
struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
@@ -355,6 +403,7 @@ typedef struct drm_i915_private {
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
unsigned int lvds_use_ssc:1;
+ unsigned int display_clock_mode:1;
int lvds_ssc_freq;
struct {
int rate;
@@ -372,7 +421,7 @@ typedef struct drm_i915_private {
struct notifier_block lid_notifier;
int crt_ddc_pin;
- struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
+ struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -503,7 +552,7 @@ typedef struct drm_i915_private {
u8 saveAR[21];
u8 saveDACMASK;
u8 saveCR[37];
- uint64_t saveFENCE[16];
+ uint64_t saveFENCE[I915_MAX_NUM_FENCES];
u32 saveCURACNTR;
u32 saveCURAPOS;
u32 saveCURABASE;
@@ -564,6 +613,9 @@ typedef struct drm_i915_private {
struct io_mapping *gtt_mapping;
int gtt_mtrr;
+ /** PPGTT used for aliasing the PPGTT with the GTT */
+ struct i915_hw_ppgtt *aliasing_ppgtt;
+
struct shrinker inactive_shrinker;
/**
@@ -670,10 +722,9 @@ typedef struct drm_i915_private {
unsigned int lvds_border_bits;
/* Panel fitter placement and size for Ironlake+ */
u32 pch_pf_pos, pch_pf_size;
- int panel_t3, panel_t12;
- struct drm_crtc *plane_to_crtc_mapping[2];
- struct drm_crtc *pipe_to_crtc_mapping[2];
+ struct drm_crtc *plane_to_crtc_mapping[3];
+ struct drm_crtc *pipe_to_crtc_mapping[3];
wait_queue_head_t pending_flip_queue;
bool flip_pending_is_done;
@@ -689,6 +740,7 @@ typedef struct drm_i915_private {
int child_dev_num;
struct child_device_config *child_dev;
struct drm_connector *int_lvds_connector;
+ struct drm_connector *int_edp_connector;
bool mchbar_need_disable;
@@ -723,12 +775,19 @@ typedef struct drm_i915_private {
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
+ struct backlight_device *backlight;
+
struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;
-
- atomic_t forcewake_count;
} drm_i915_private_t;
+enum hdmi_force_audio {
+ HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */
+ HDMI_AUDIO_OFF, /* force turn off HDMI audio */
+ HDMI_AUDIO_AUTO, /* trust EDID */
+ HDMI_AUDIO_ON, /* force turn on HDMI audio */
+};
+
enum i915_cache_level {
I915_CACHE_NONE,
I915_CACHE_LLC,
@@ -755,39 +814,37 @@ struct drm_i915_gem_object {
* (has pending rendering), and is not set if it's on inactive (ready
* to be unbound).
*/
- unsigned int active : 1;
+ unsigned int active:1;
/**
* This is set if the object has been written to since last bound
* to the GTT
*/
- unsigned int dirty : 1;
+ unsigned int dirty:1;
/**
* This is set if the object has been written to since the last
* GPU flush.
*/
- unsigned int pending_gpu_write : 1;
+ unsigned int pending_gpu_write:1;
/**
* Fence register bits (if any) for this object. Will be set
* as needed when mapped into the GTT.
* Protected by dev->struct_mutex.
- *
- * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE)
*/
- signed int fence_reg : 5;
+ signed int fence_reg:I915_MAX_NUM_FENCE_BITS;
/**
* Advice: are the backing pages purgeable?
*/
- unsigned int madv : 2;
+ unsigned int madv:2;
/**
* Current tiling mode for the object.
*/
- unsigned int tiling_mode : 2;
- unsigned int tiling_changed : 1;
+ unsigned int tiling_mode:2;
+ unsigned int tiling_changed:1;
/** How many users have pinned this object in GTT space. The following
* users can each hold at most one reference: pwrite/pread, pin_ioctl
@@ -798,22 +855,22 @@ struct drm_i915_gem_object {
*
* In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
* bits with absolutely no headroom. So use 4 bits. */
- unsigned int pin_count : 4;
+ unsigned int pin_count:4;
#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
/**
* Is the object at the current location in the gtt mappable and
* fenceable? Used to avoid costly recalculations.
*/
- unsigned int map_and_fenceable : 1;
+ unsigned int map_and_fenceable:1;
/**
* Whether the current gtt mapping needs to be mappable (and isn't just
* mappable by accident). Track pin and fault separate for a more
* accurate mappable working set.
*/
- unsigned int fault_mappable : 1;
- unsigned int pin_mappable : 1;
+ unsigned int fault_mappable:1;
+ unsigned int pin_mappable:1;
/*
* Is the GPU currently using a fence to access this buffer,
@@ -823,6 +880,8 @@ struct drm_i915_gem_object {
unsigned int cache_level:2;
+ unsigned int has_aliasing_ppgtt_mapping:1;
+
struct page **pages;
/**
@@ -900,6 +959,9 @@ struct drm_i915_gem_request {
/** GEM sequence number associated with this request. */
uint32_t seqno;
+ /** Postion in the ringbuffer of the end of the request */
+ u32 tail;
+
/** Time at which this request was emitted, in jiffies. */
unsigned long emitted_jiffies;
@@ -956,8 +1018,11 @@ struct drm_i915_file_private {
#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring)
+#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc)
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
+#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6)
+
#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay)
#define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical)
@@ -990,15 +1055,17 @@ struct drm_i915_file_private {
extern struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
-extern unsigned int i915_fbpercrtc;
-extern int i915_panel_ignore_lid;
-extern unsigned int i915_powersave;
-extern unsigned int i915_semaphores;
-extern unsigned int i915_lvds_downclock;
-extern unsigned int i915_panel_use_ssc;
-extern int i915_vbt_sdvo_panel_type;
-extern unsigned int i915_enable_rc6;
-extern unsigned int i915_enable_fbc;
+extern unsigned int i915_fbpercrtc __always_unused;
+extern int i915_panel_ignore_lid __read_mostly;
+extern unsigned int i915_powersave __read_mostly;
+extern int i915_semaphores __read_mostly;
+extern unsigned int i915_lvds_downclock __read_mostly;
+extern int i915_panel_use_ssc __read_mostly;
+extern int i915_vbt_sdvo_panel_type __read_mostly;
+extern int i915_enable_rc6 __read_mostly;
+extern int i915_enable_fbc __read_mostly;
+extern bool i915_enable_hangcheck __read_mostly;
+extern bool i915_enable_ppgtt __read_mostly;
extern int i915_suspend(struct drm_device *dev, pm_message_t state);
extern int i915_resume(struct drm_device *dev);
@@ -1051,7 +1118,7 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
-void intel_enable_asle (struct drm_device *dev);
+void intel_enable_asle(struct drm_device *dev);
#ifdef CONFIG_DEBUG_FS
extern void i915_destroy_error_state(struct drm_device *dev);
@@ -1060,18 +1127,6 @@ extern void i915_destroy_error_state(struct drm_device *dev);
#endif
-/* i915_mem.c */
-extern int i915_mem_alloc(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int i915_mem_free(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int i915_mem_init_heap(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern void i915_mem_takedown(struct mem_block **heap);
-extern void i915_mem_release(struct drm_device * dev,
- struct drm_file *file_priv, struct mem_block *heap);
/* i915_gem.c */
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -1141,7 +1196,7 @@ int i915_gem_dumb_create(struct drm_file *file_priv,
int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev,
- uint32_t handle);
+ uint32_t handle);
/**
* Returns true if seq1 is later than seq2.
*/
@@ -1151,43 +1206,62 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
return (int32_t)(seq1 - seq2) >= 0;
}
-static inline u32
-i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
-{
- drm_i915_private_t *dev_priv = ring->dev->dev_private;
- return ring->outstanding_lazy_request = dev_priv->next_seqno;
-}
+u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring);
int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *pipelined);
int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
+static inline void
+i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
+{
+ if (obj->fence_reg != I915_FENCE_REG_NONE) {
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ dev_priv->fence_regs[obj->fence_reg].pin_count++;
+ }
+}
+
+static inline void
+i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
+{
+ if (obj->fence_reg != I915_FENCE_REG_NONE) {
+ struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+ dev_priv->fence_regs[obj->fence_reg].pin_count--;
+ }
+}
+
void i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
+
void i915_gem_reset(struct drm_device *dev);
void i915_gem_clflush_object(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj,
uint32_t read_domains,
uint32_t write_domain);
-int __must_check i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj);
-int __must_check i915_gem_init_ringbuffer(struct drm_device *dev);
+int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
+int __must_check i915_gem_init_hw(struct drm_device *dev);
+void i915_gem_init_swizzling(struct drm_device *dev);
+void i915_gem_init_ppgtt(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
void i915_gem_do_init(struct drm_device *dev,
unsigned long start,
unsigned long mappable_end,
unsigned long end);
-int __must_check i915_gpu_idle(struct drm_device *dev);
+int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire);
int __must_check i915_gem_idle(struct drm_device *dev);
int __must_check i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
struct drm_i915_gem_request *request);
int __must_check i915_wait_request(struct intel_ring_buffer *ring,
- uint32_t seqno);
+ uint32_t seqno,
+ bool do_retire);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int __must_check
i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
bool write);
int __must_check
-i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj,
+i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
+ u32 alignment,
struct intel_ring_buffer *pipelined);
int i915_gem_attach_phys_object(struct drm_device *dev,
struct drm_i915_gem_object *obj,
@@ -1203,9 +1277,22 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev,
uint32_t size,
int tiling_mode);
+int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
+ enum i915_cache_level cache_level);
+
/* i915_gem_gtt.c */
+int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev);
+void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev);
+void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
+ struct drm_i915_gem_object *obj,
+ enum i915_cache_level cache_level);
+void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
+ struct drm_i915_gem_object *obj);
+
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj);
+void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj,
+ enum i915_cache_level cache_level);
void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj);
/* i915_gem_evict.c */
@@ -1287,17 +1374,19 @@ extern void intel_modeset_init(struct drm_device *dev);
extern void intel_modeset_gem_init(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
-extern void i8xx_disable_fbc(struct drm_device *dev);
-extern void g4x_disable_fbc(struct drm_device *dev);
-extern void ironlake_disable_fbc(struct drm_device *dev);
-extern void intel_disable_fbc(struct drm_device *dev);
-extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
extern bool intel_fbc_enabled(struct drm_device *dev);
+extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
+extern void ironlake_init_pch_refclk(struct drm_device *dev);
extern void ironlake_enable_rc6(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val);
-extern void intel_detect_pch (struct drm_device *dev);
-extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
+extern void intel_detect_pch(struct drm_device *dev);
+extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
+
+extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
/* overlay */
#ifdef CONFIG_DEBUG_FS
@@ -1338,27 +1427,16 @@ extern void intel_display_print_error_state(struct seq_file *m,
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
-void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
+int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE))
#define __i915_read(x, y) \
-static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
- u##x val = 0; \
- if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- gen6_gt_force_wake_get(dev_priv); \
- val = read##y(dev_priv->regs + reg); \
- gen6_gt_force_wake_put(dev_priv); \
- } else { \
- val = read##y(dev_priv->regs + reg); \
- } \
- trace_i915_reg_rw(false, reg, val, sizeof(val)); \
- return val; \
-}
+ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
__i915_read(8, b)
__i915_read(16, w)
@@ -1367,13 +1445,8 @@ __i915_read(64, q)
#undef __i915_read
#define __i915_write(x, y) \
-static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
- trace_i915_reg_rw(true, reg, val, sizeof(val)); \
- if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- __gen6_gt_wait_for_fifo(dev_priv); \
- } \
- write##y(val, dev_priv->regs + reg); \
-}
+ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val);
+
__i915_write(8, b)
__i915_write(16, w)
__i915_write(32, l)
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_gem.c smdk4210/drivers/gpu/drm/i915/i915_gem.c
index 5548593..1f441f5 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_gem.c
+++ smdk4210/drivers/gpu/drm/i915/i915_gem.c
@@ -58,6 +58,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj);
static int i915_gem_inactive_shrink(struct shrinker *shrinker,
struct shrink_control *sc);
+static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
/* some bookkeeping */
static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
@@ -179,7 +180,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex);
args->aper_size = dev_priv->mm.gtt_total;
- args->aper_available_size = args->aper_size -pinned;
+ args->aper_available_size = args->aper_size - pinned;
return 0;
}
@@ -195,6 +196,8 @@ i915_gem_create(struct drm_file *file,
u32 handle;
size = roundup(size, PAGE_SIZE);
+ if (size == 0)
+ return -EINVAL;
/* Allocate the new object */
obj = i915_gem_alloc_object(dev, size);
@@ -256,73 +259,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
obj->tiling_mode != I915_TILING_NONE;
}
-static inline void
-slow_shmem_copy(struct page *dst_page,
- int dst_offset,
- struct page *src_page,
- int src_offset,
- int length)
-{
- char *dst_vaddr, *src_vaddr;
-
- dst_vaddr = kmap(dst_page);
- src_vaddr = kmap(src_page);
-
- memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
-
- kunmap(src_page);
- kunmap(dst_page);
-}
-
-static inline void
-slow_shmem_bit17_copy(struct page *gpu_page,
- int gpu_offset,
- struct page *cpu_page,
- int cpu_offset,
- int length,
- int is_read)
-{
- char *gpu_vaddr, *cpu_vaddr;
-
- /* Use the unswizzled path if this page isn't affected. */
- if ((page_to_phys(gpu_page) & (1 << 17)) == 0) {
- if (is_read)
- return slow_shmem_copy(cpu_page, cpu_offset,
- gpu_page, gpu_offset, length);
- else
- return slow_shmem_copy(gpu_page, gpu_offset,
- cpu_page, cpu_offset, length);
- }
-
- gpu_vaddr = kmap(gpu_page);
- cpu_vaddr = kmap(cpu_page);
-
- /* Copy the data, XORing A6 with A17 (1). The user already knows he's
- * XORing with the other bits (A9 for Y, A9 and A10 for X)
- */
- while (length > 0) {
- int cacheline_end = ALIGN(gpu_offset + 1, 64);
- int this_length = min(cacheline_end - gpu_offset, length);
- int swizzled_gpu_offset = gpu_offset ^ 64;
-
- if (is_read) {
- memcpy(cpu_vaddr + cpu_offset,
- gpu_vaddr + swizzled_gpu_offset,
- this_length);
- } else {
- memcpy(gpu_vaddr + swizzled_gpu_offset,
- cpu_vaddr + cpu_offset,
- this_length);
- }
- cpu_offset += this_length;
- gpu_offset += this_length;
- length -= this_length;
- }
-
- kunmap(cpu_page);
- kunmap(gpu_page);
-}
-
/**
* This is the fast shmem pread path, which attempts to copy_from_user directly
* from the backing pages of the object to the user's address space. On a
@@ -383,6 +319,58 @@ i915_gem_shmem_pread_fast(struct drm_device *dev,
return 0;
}
+static inline int
+__copy_to_user_swizzled(char __user *cpu_vaddr,
+ const char *gpu_vaddr, int gpu_offset,
+ int length)
+{
+ int ret, cpu_offset = 0;
+
+ while (length > 0) {
+ int cacheline_end = ALIGN(gpu_offset + 1, 64);
+ int this_length = min(cacheline_end - gpu_offset, length);
+ int swizzled_gpu_offset = gpu_offset ^ 64;
+
+ ret = __copy_to_user(cpu_vaddr + cpu_offset,
+ gpu_vaddr + swizzled_gpu_offset,
+ this_length);
+ if (ret)
+ return ret + length;
+
+ cpu_offset += this_length;
+ gpu_offset += this_length;
+ length -= this_length;
+ }
+
+ return 0;
+}
+
+static inline int
+__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset,
+ const char *cpu_vaddr,
+ int length)
+{
+ int ret, cpu_offset = 0;
+
+ while (length > 0) {
+ int cacheline_end = ALIGN(gpu_offset + 1, 64);
+ int this_length = min(cacheline_end - gpu_offset, length);
+ int swizzled_gpu_offset = gpu_offset ^ 64;
+
+ ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset,
+ cpu_vaddr + cpu_offset,
+ this_length);
+ if (ret)
+ return ret + length;
+
+ cpu_offset += this_length;
+ gpu_offset += this_length;
+ length -= this_length;
+ }
+
+ return 0;
+}
+
/**
* This is the fallback shmem pread path, which allocates temporary storage
* in kernel space to copy_to_user into outside of the struct_mutex, so we
@@ -396,72 +384,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
struct drm_file *file)
{
struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
- struct mm_struct *mm = current->mm;
- struct page **user_pages;
+ char __user *user_data;
ssize_t remain;
- loff_t offset, pinned_pages, i;
- loff_t first_data_page, last_data_page, num_pages;
- int shmem_page_offset;
- int data_page_index, data_page_offset;
- int page_length;
- int ret;
- uint64_t data_ptr = args->data_ptr;
- int do_bit17_swizzling;
+ loff_t offset;
+ int shmem_page_offset, page_length, ret;
+ int obj_do_bit17_swizzling, page_do_bit17_swizzling;
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
- /* Pin the user pages containing the data. We can't fault while
- * holding the struct mutex, yet we want to hold it while
- * dereferencing the user data.
- */
- first_data_page = data_ptr / PAGE_SIZE;
- last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
- num_pages = last_data_page - first_data_page + 1;
+ obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
- user_pages = drm_malloc_ab(num_pages, sizeof(struct page *));
- if (user_pages == NULL)
- return -ENOMEM;
+ offset = args->offset;
mutex_unlock(&dev->struct_mutex);
- down_read(&mm->mmap_sem);
- pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
- num_pages, 1, 0, user_pages, NULL);
- up_read(&mm->mmap_sem);
- mutex_lock(&dev->struct_mutex);
- if (pinned_pages < num_pages) {
- ret = -EFAULT;
- goto out;
- }
-
- ret = i915_gem_object_set_cpu_read_domain_range(obj,
- args->offset,
- args->size);
- if (ret)
- goto out;
-
- do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
-
- offset = args->offset;
while (remain > 0) {
struct page *page;
+ char *vaddr;
/* Operation in this page
*
* shmem_page_offset = offset within page in shmem file
- * data_page_index = page number in get_user_pages return
- * data_page_offset = offset with data_page_index page.
* page_length = bytes to copy for this page
*/
shmem_page_offset = offset_in_page(offset);
- data_page_index = data_ptr / PAGE_SIZE - first_data_page;
- data_page_offset = offset_in_page(data_ptr);
-
page_length = remain;
if ((shmem_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - shmem_page_offset;
- if ((data_page_offset + page_length) > PAGE_SIZE)
- page_length = PAGE_SIZE - data_page_offset;
page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page)) {
@@ -469,36 +419,38 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
goto out;
}
- if (do_bit17_swizzling) {
- slow_shmem_bit17_copy(page,
- shmem_page_offset,
- user_pages[data_page_index],
- data_page_offset,
- page_length,
- 1);
- } else {
- slow_shmem_copy(user_pages[data_page_index],
- data_page_offset,
- page,
- shmem_page_offset,
- page_length);
- }
+ page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+ (page_to_phys(page) & (1 << 17)) != 0;
+
+ vaddr = kmap(page);
+ if (page_do_bit17_swizzling)
+ ret = __copy_to_user_swizzled(user_data,
+ vaddr, shmem_page_offset,
+ page_length);
+ else
+ ret = __copy_to_user(user_data,
+ vaddr + shmem_page_offset,
+ page_length);
+ kunmap(page);
mark_page_accessed(page);
page_cache_release(page);
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+
remain -= page_length;
- data_ptr += page_length;
+ user_data += page_length;
offset += page_length;
}
out:
- for (i = 0; i < pinned_pages; i++) {
- SetPageDirty(user_pages[i]);
- mark_page_accessed(user_pages[i]);
- page_cache_release(user_pages[i]);
- }
- drm_free_large(user_pages);
+ mutex_lock(&dev->struct_mutex);
+ /* Fixup: Kill any reinstated backing storage pages */
+ if (obj->madv == __I915_MADV_PURGED)
+ i915_gem_object_truncate(obj);
return ret;
}
@@ -800,11 +752,11 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev,
if (IS_ERR(page))
return PTR_ERR(page);
- vaddr = kmap_atomic(page, KM_USER0);
+ vaddr = kmap_atomic(page);
ret = __copy_from_user_inatomic(vaddr + page_offset,
user_data,
page_length);
- kunmap_atomic(vaddr, KM_USER0);
+ kunmap_atomic(vaddr);
set_page_dirty(page);
mark_page_accessed(page);
@@ -839,71 +791,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
struct drm_file *file)
{
struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
- struct mm_struct *mm = current->mm;
- struct page **user_pages;
ssize_t remain;
- loff_t offset, pinned_pages, i;
- loff_t first_data_page, last_data_page, num_pages;
- int shmem_page_offset;
- int data_page_index, data_page_offset;
- int page_length;
- int ret;
- uint64_t data_ptr = args->data_ptr;
- int do_bit17_swizzling;
+ loff_t offset;
+ char __user *user_data;
+ int shmem_page_offset, page_length, ret;
+ int obj_do_bit17_swizzling, page_do_bit17_swizzling;
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
remain = args->size;
- /* Pin the user pages containing the data. We can't fault while
- * holding the struct mutex, and all of the pwrite implementations
- * want to hold it while dereferencing the user data.
- */
- first_data_page = data_ptr / PAGE_SIZE;
- last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
- num_pages = last_data_page - first_data_page + 1;
-
- user_pages = drm_malloc_ab(num_pages, sizeof(struct page *));
- if (user_pages == NULL)
- return -ENOMEM;
-
- mutex_unlock(&dev->struct_mutex);
- down_read(&mm->mmap_sem);
- pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
- num_pages, 0, 0, user_pages, NULL);
- up_read(&mm->mmap_sem);
- mutex_lock(&dev->struct_mutex);
- if (pinned_pages < num_pages) {
- ret = -EFAULT;
- goto out;
- }
-
- ret = i915_gem_object_set_to_cpu_domain(obj, 1);
- if (ret)
- goto out;
-
- do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+ obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
offset = args->offset;
obj->dirty = 1;
+ mutex_unlock(&dev->struct_mutex);
+
while (remain > 0) {
struct page *page;
+ char *vaddr;
/* Operation in this page
*
* shmem_page_offset = offset within page in shmem file
- * data_page_index = page number in get_user_pages return
- * data_page_offset = offset with data_page_index page.
* page_length = bytes to copy for this page
*/
shmem_page_offset = offset_in_page(offset);
- data_page_index = data_ptr / PAGE_SIZE - first_data_page;
- data_page_offset = offset_in_page(data_ptr);
page_length = remain;
if ((shmem_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - shmem_page_offset;
- if ((data_page_offset + page_length) > PAGE_SIZE)
- page_length = PAGE_SIZE - data_page_offset;
page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page)) {
@@ -911,34 +828,45 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
goto out;
}
- if (do_bit17_swizzling) {
- slow_shmem_bit17_copy(page,
- shmem_page_offset,
- user_pages[data_page_index],
- data_page_offset,
- page_length,
- 0);
- } else {
- slow_shmem_copy(page,
- shmem_page_offset,
- user_pages[data_page_index],
- data_page_offset,
- page_length);
- }
+ page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+ (page_to_phys(page) & (1 << 17)) != 0;
+
+ vaddr = kmap(page);
+ if (page_do_bit17_swizzling)
+ ret = __copy_from_user_swizzled(vaddr, shmem_page_offset,
+ user_data,
+ page_length);
+ else
+ ret = __copy_from_user(vaddr + shmem_page_offset,
+ user_data,
+ page_length);
+ kunmap(page);
set_page_dirty(page);
mark_page_accessed(page);
page_cache_release(page);
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+
remain -= page_length;
- data_ptr += page_length;
+ user_data += page_length;
offset += page_length;
}
out:
- for (i = 0; i < pinned_pages; i++)
- page_cache_release(user_pages[i]);
- drm_free_large(user_pages);
+ mutex_lock(&dev->struct_mutex);
+ /* Fixup: Kill any reinstated backing storage pages */
+ if (obj->madv == __I915_MADV_PURGED)
+ i915_gem_object_truncate(obj);
+ /* and flush dirty cachelines in case the object isn't in the cpu write
+ * domain anymore. */
+ if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+ i915_gem_clflush_object(obj);
+ intel_gtt_chipset_flush();
+ }
return ret;
}
@@ -994,10 +922,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
* pread/pwrite currently are reading and writing from the CPU
* perspective, requiring manual detiling by the client.
*/
- if (obj->phys_obj)
+ if (obj->phys_obj) {
ret = i915_gem_phys_pwrite(dev, obj, args, file);
- else if (obj->gtt_space &&
- obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+ goto out;
+ }
+
+ if (obj->gtt_space &&
+ obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
ret = i915_gem_object_pin(obj, 0, true);
if (ret)
goto out;
@@ -1016,18 +947,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
out_unpin:
i915_gem_object_unpin(obj);
- } else {
- ret = i915_gem_object_set_to_cpu_domain(obj, 1);
- if (ret)
- goto out;
- ret = -EFAULT;
- if (!i915_gem_object_needs_bit17_swizzle(obj))
- ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file);
- if (ret == -EFAULT)
- ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file);
+ if (ret != -EFAULT)
+ goto out;
+ /* Fall through to the shmfs paths because the gtt paths might
+ * fail with non-page-backed user pointers (e.g. gtt mappings
+ * when moving data between textures). */
}
+ ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+ if (ret)
+ goto out;
+
+ ret = -EFAULT;
+ if (!i915_gem_object_needs_bit17_swizzle(obj))
+ ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file);
+ if (ret == -EFAULT)
+ ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file);
+
out:
drm_gem_object_unreference(&obj->base);
unlock:
@@ -1139,7 +1076,6 @@ int
i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_mmap *args = data;
struct drm_gem_object *obj;
unsigned long addr;
@@ -1151,11 +1087,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
if (obj == NULL)
return -ENOENT;
- if (obj->size > dev_priv->mm.gtt_mappable_end) {
- drm_gem_object_unreference_unlocked(obj);
- return -E2BIG;
- }
-
down_write(&current->mm->mmap_sem);
addr = do_mmap(obj->filp, 0, args->size,
PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -1265,74 +1196,6 @@ out:
}
/**
- * i915_gem_create_mmap_offset - create a fake mmap offset for an object
- * @obj: obj in question
- *
- * GEM memory mapping works by handing back to userspace a fake mmap offset
- * it can use in a subsequent mmap(2) call. The DRM core code then looks
- * up the object based on the offset and sets up the various memory mapping
- * structures.
- *
- * This routine allocates and attaches a fake offset for @obj.
- */
-static int
-i915_gem_create_mmap_offset(struct drm_i915_gem_object *obj)
-{
- struct drm_device *dev = obj->base.dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret = 0;
-
- /* Set the object up for mmap'ing */
- list = &obj->base.map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
- if (!list->map)
- return -ENOMEM;
-
- map = list->map;
- map->type = _DRM_GEM;
- map->size = obj->base.size;
- map->handle = obj;
-
- /* Get a DRM GEM mmap offset allocated... */
- list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
- obj->base.size / PAGE_SIZE,
- 0, 0);
- if (!list->file_offset_node) {
- DRM_ERROR("failed to allocate offset for bo %d\n",
- obj->base.name);
- ret = -ENOSPC;
- goto out_free_list;
- }
-
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
- obj->base.size / PAGE_SIZE,
- 0);
- if (!list->file_offset_node) {
- ret = -ENOMEM;
- goto out_free_list;
- }
-
- list->hash.key = list->file_offset_node->start;
- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
- if (ret) {
- DRM_ERROR("failed to add to map hash\n");
- goto out_free_mm;
- }
-
- return 0;
-
-out_free_mm:
- drm_mm_put_block(list->file_offset_node);
-out_free_list:
- kfree(list->map);
- list->map = NULL;
-
- return ret;
-}
-
-/**
* i915_gem_release_mmap - remove physical page mappings
* @obj: obj in question
*
@@ -1360,19 +1223,6 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
obj->fault_mappable = false;
}
-static void
-i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj)
-{
- struct drm_device *dev = obj->base.dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list = &obj->base.map_list;
-
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
- drm_mm_put_block(list->file_offset_node);
- kfree(list->map);
- list->map = NULL;
-}
-
static uint32_t
i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
{
@@ -1485,7 +1335,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
}
if (!obj->base.map_list.map) {
- ret = i915_gem_create_mmap_offset(obj);
+ ret = drm_gem_create_mmap_offset(&obj->base);
if (ret)
goto out;
}
@@ -1557,7 +1407,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
obj->pages[i] = page;
}
- if (obj->tiling_mode != I915_TILING_NONE)
+ if (i915_gem_object_needs_bit17_swizzle(obj))
i915_gem_object_do_bit_17_swizzle(obj);
return 0;
@@ -1579,7 +1429,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
BUG_ON(obj->madv == __I915_MADV_PURGED);
- if (obj->tiling_mode != I915_TILING_NONE)
+ if (i915_gem_object_needs_bit17_swizzle(obj))
i915_gem_object_save_bit_17_swizzle(obj);
if (obj->madv == I915_MADV_DONTNEED)
@@ -1726,6 +1576,28 @@ i915_gem_process_flushing_list(struct intel_ring_buffer *ring,
}
}
+static u32
+i915_gem_get_seqno(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ u32 seqno = dev_priv->next_seqno;
+
+ /* reserve 0 for non-seqno */
+ if (++dev_priv->next_seqno == 0)
+ dev_priv->next_seqno = 1;
+
+ return seqno;
+}
+
+u32
+i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
+{
+ if (ring->outstanding_lazy_request == 0)
+ ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev);
+
+ return ring->outstanding_lazy_request;
+}
+
int
i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
@@ -1733,10 +1605,19 @@ i915_add_request(struct intel_ring_buffer *ring,
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
uint32_t seqno;
+ u32 request_ring_position;
int was_empty;
int ret;
BUG_ON(request == NULL);
+ seqno = i915_gem_next_request_seqno(ring);
+
+ /* Record the position of the start of the request so that
+ * should we detect the updated seqno part-way through the
+ * GPU processing the request, we never over-estimate the
+ * position of the head.
+ */
+ request_ring_position = intel_ring_get_tail(ring);
ret = ring->add_request(ring, &seqno);
if (ret)
@@ -1746,6 +1627,7 @@ i915_add_request(struct intel_ring_buffer *ring,
request->seqno = seqno;
request->ring = ring;
+ request->tail = request_ring_position;
request->emitted_jiffies = jiffies;
was_empty = list_empty(&ring->request_list);
list_add_tail(&request->list, &ring->request_list);
@@ -1760,11 +1642,14 @@ i915_add_request(struct intel_ring_buffer *ring,
spin_unlock(&file_priv->mm.lock);
}
- ring->outstanding_lazy_request = false;
+ ring->outstanding_lazy_request = 0;
if (!dev_priv->mm.suspended) {
- mod_timer(&dev_priv->hangcheck_timer,
- jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
+ if (i915_enable_hangcheck) {
+ mod_timer(&dev_priv->hangcheck_timer,
+ jiffies +
+ msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
+ }
if (was_empty)
queue_delayed_work(dev_priv->wq,
&dev_priv->mm.retire_work, HZ);
@@ -1821,7 +1706,7 @@ static void i915_gem_reset_fences(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < dev_priv->num_fence_regs; i++) {
struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
struct drm_i915_gem_object *obj = reg->obj;
@@ -1853,7 +1738,7 @@ void i915_gem_reset(struct drm_device *dev)
* lost bo to the inactive list.
*/
while (!list_empty(&dev_priv->mm.flushing_list)) {
- obj= list_first_entry(&dev_priv->mm.flushing_list,
+ obj = list_first_entry(&dev_priv->mm.flushing_list,
struct drm_i915_gem_object,
mm_list);
@@ -1879,7 +1764,7 @@ void i915_gem_reset(struct drm_device *dev)
/**
* This function clears the request list as sequence numbers are passed.
*/
-static void
+void
i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
{
uint32_t seqno;
@@ -1907,6 +1792,12 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
break;
trace_i915_gem_request_retire(ring, request->seqno);
+ /* We know the GPU must have read the request to have
+ * sent us the seqno + interrupt, so use the position
+ * of tail of the request to update the last known position
+ * of the GPU head.
+ */
+ ring->last_retired_head = request->tail;
list_del(&request->list);
i915_gem_request_remove_from_client(request);
@@ -1919,7 +1810,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
while (!list_empty(&ring->active_list)) {
struct drm_i915_gem_object *obj;
- obj= list_first_entry(&ring->active_list,
+ obj = list_first_entry(&ring->active_list,
struct drm_i915_gem_object,
ring_list);
@@ -2019,7 +1910,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
*/
int
i915_wait_request(struct intel_ring_buffer *ring,
- uint32_t seqno)
+ uint32_t seqno,
+ bool do_retire)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
u32 ier;
@@ -2082,9 +1974,9 @@ i915_wait_request(struct intel_ring_buffer *ring,
|| atomic_read(&dev_priv->mm.wedged));
ring->irq_put(ring);
- } else if (wait_for(i915_seqno_passed(ring->get_seqno(ring),
- seqno) ||
- atomic_read(&dev_priv->mm.wedged), 3000))
+ } else if (wait_for_atomic(i915_seqno_passed(ring->get_seqno(ring),
+ seqno) ||
+ atomic_read(&dev_priv->mm.wedged), 3000))
ret = -EBUSY;
ring->waiting_seqno = 0;
@@ -2093,17 +1985,12 @@ i915_wait_request(struct intel_ring_buffer *ring,
if (atomic_read(&dev_priv->mm.wedged))
ret = -EAGAIN;
- if (ret && ret != -ERESTARTSYS)
- DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n",
- __func__, ret, seqno, ring->get_seqno(ring),
- dev_priv->next_seqno);
-
/* Directly dispatch request retiring. While we have the work queue
* to handle this, the waiter on a request often wants an associated
* buffer to have made it to the inactive list, and we would need
* a separate wait queue to handle that.
*/
- if (ret == 0)
+ if (ret == 0 && do_retire)
i915_gem_retire_requests_ring(ring);
return ret;
@@ -2127,7 +2014,8 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj)
* it.
*/
if (obj->active) {
- ret = i915_wait_request(obj->ring, obj->last_rendering_seqno);
+ ret = i915_wait_request(obj->ring, obj->last_rendering_seqno,
+ true);
if (ret)
return ret;
}
@@ -2135,12 +2023,37 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj)
return 0;
}
+static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj)
+{
+ u32 old_write_domain, old_read_domains;
+
+ /* Act a barrier for all accesses through the GTT */
+ mb();
+
+ /* Force a pagefault for domain tracking on next user access */
+ i915_gem_release_mmap(obj);
+
+ if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
+ return;
+
+ old_read_domains = obj->base.read_domains;
+ old_write_domain = obj->base.write_domain;
+
+ obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT;
+ obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT;
+
+ trace_i915_gem_object_change_domain(obj,
+ old_read_domains,
+ old_write_domain);
+}
+
/**
* Unbinds an object from the GTT aperture.
*/
int
i915_gem_object_unbind(struct drm_i915_gem_object *obj)
{
+ drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
int ret = 0;
if (obj->gtt_space == NULL)
@@ -2151,23 +2064,28 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
return -EINVAL;
}
- /* blow away mappings if mapped through GTT */
- i915_gem_release_mmap(obj);
-
- /* Move the object to the CPU domain to ensure that
- * any possible CPU writes while it's not in the GTT
- * are flushed when we go to remap it. This will
- * also ensure that all pending GPU writes are finished
- * before we unbind.
- */
- ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+ ret = i915_gem_object_finish_gpu(obj);
if (ret == -ERESTARTSYS)
return ret;
/* Continue on if we fail due to EIO, the GPU is hung so we
* should be safe and we need to cleanup or else we might
* cause memory corruption through use-after-free.
*/
+
+ i915_gem_object_finish_gtt(obj);
+
+ /* Move the object to the CPU domain to ensure that
+ * any possible CPU writes while it's not in the GTT
+ * are flushed when we go to remap it.
+ */
+ if (ret == 0)
+ ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+ if (ret == -ERESTARTSYS)
+ return ret;
if (ret) {
+ /* In the event of a disaster, abandon all caches and
+ * hope for the best.
+ */
i915_gem_clflush_object(obj);
obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
}
@@ -2180,6 +2098,11 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
trace_i915_gem_object_unbind(obj);
i915_gem_gtt_unbind_object(obj);
+ if (obj->has_aliasing_ppgtt_mapping) {
+ i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj);
+ obj->has_aliasing_ppgtt_mapping = 0;
+ }
+
i915_gem_object_put_pages_gtt(obj);
list_del_init(&obj->gtt_list);
@@ -2219,7 +2142,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring,
return 0;
}
-static int i915_ring_idle(struct intel_ring_buffer *ring)
+static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire)
{
int ret;
@@ -2233,24 +2156,18 @@ static int i915_ring_idle(struct intel_ring_buffer *ring)
return ret;
}
- return i915_wait_request(ring, i915_gem_next_request_seqno(ring));
+ return i915_wait_request(ring, i915_gem_next_request_seqno(ring),
+ do_retire);
}
-int
-i915_gpu_idle(struct drm_device *dev)
+int i915_gpu_idle(struct drm_device *dev, bool do_retire)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- bool lists_empty;
int ret, i;
- lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->mm.active_list));
- if (lists_empty)
- return 0;
-
/* Flush everything onto the inactive list. */
for (i = 0; i < I915_NUM_RINGS; i++) {
- ret = i915_ring_idle(&dev_priv->ring[i]);
+ ret = i915_ring_idle(&dev_priv->ring[i], do_retire);
if (ret)
return ret;
}
@@ -2453,7 +2370,8 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
if (!ring_passed_seqno(obj->last_fenced_ring,
obj->last_fenced_seqno)) {
ret = i915_wait_request(obj->last_fenced_ring,
- obj->last_fenced_seqno);
+ obj->last_fenced_seqno,
+ true);
if (ret)
return ret;
}
@@ -2485,6 +2403,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
if (obj->fence_reg != I915_FENCE_REG_NONE) {
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+ WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count);
i915_gem_clear_fence_reg(obj->base.dev,
&dev_priv->fence_regs[obj->fence_reg]);
@@ -2509,7 +2429,7 @@ i915_find_fence_reg(struct drm_device *dev,
if (!reg->obj)
return reg;
- if (!reg->obj->pin_count)
+ if (!reg->pin_count)
avail = reg;
}
@@ -2519,7 +2439,7 @@ i915_find_fence_reg(struct drm_device *dev,
/* None available, try to steal one or wait for a user to finish */
avail = first = NULL;
list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
- if (reg->obj->pin_count)
+ if (reg->pin_count)
continue;
if (first == NULL)
@@ -2594,7 +2514,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
if (!ring_passed_seqno(obj->last_fenced_ring,
reg->setup_seqno)) {
ret = i915_wait_request(obj->last_fenced_ring,
- reg->setup_seqno);
+ reg->setup_seqno,
+ true);
if (ret)
return ret;
}
@@ -2613,7 +2534,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
reg = i915_find_fence_reg(dev, pipelined);
if (reg == NULL)
- return -ENOSPC;
+ return -EDEADLK;
ret = i915_gem_object_flush_fence(obj, pipelined);
if (ret)
@@ -2713,6 +2634,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev,
list_del_init(&reg->lru_list);
reg->obj = NULL;
reg->setup_seqno = 0;
+ reg->pin_count = 0;
}
/**
@@ -2850,7 +2772,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
fenceable =
obj->gtt_space->size == fence_size &&
- (obj->gtt_space->start & (fence_alignment -1)) == 0;
+ (obj->gtt_space->start & (fence_alignment - 1)) == 0;
mappable =
obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
@@ -2996,51 +2918,144 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
return 0;
}
+int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
+ enum i915_cache_level cache_level)
+{
+ struct drm_device *dev = obj->base.dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ if (obj->cache_level == cache_level)
+ return 0;
+
+ if (obj->pin_count) {
+ DRM_DEBUG("can not change the cache level of pinned objects\n");
+ return -EBUSY;
+ }
+
+ if (obj->gtt_space) {
+ ret = i915_gem_object_finish_gpu(obj);
+ if (ret)
+ return ret;
+
+ i915_gem_object_finish_gtt(obj);
+
+ /* Before SandyBridge, you could not use tiling or fence
+ * registers with snooped memory, so relinquish any fences
+ * currently pointing to our region in the aperture.
+ */
+ if (INTEL_INFO(obj->base.dev)->gen < 6) {
+ ret = i915_gem_object_put_fence(obj);
+ if (ret)
+ return ret;
+ }
+
+ i915_gem_gtt_rebind_object(obj, cache_level);
+ if (obj->has_aliasing_ppgtt_mapping)
+ i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
+ obj, cache_level);
+ }
+
+ if (cache_level == I915_CACHE_NONE) {
+ u32 old_read_domains, old_write_domain;
+
+ /* If we're coming from LLC cached, then we haven't
+ * actually been tracking whether the data is in the
+ * CPU cache or not, since we only allow one bit set
+ * in obj->write_domain and have been skipping the clflushes.
+ * Just set it to the CPU cache for now.
+ */
+ WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU);
+ WARN_ON(obj->base.read_domains & ~I915_GEM_DOMAIN_CPU);
+
+ old_read_domains = obj->base.read_domains;
+ old_write_domain = obj->base.write_domain;
+
+ obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+ obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+
+ trace_i915_gem_object_change_domain(obj,
+ old_read_domains,
+ old_write_domain);
+ }
+
+ obj->cache_level = cache_level;
+ return 0;
+}
+
/*
- * Prepare buffer for display plane. Use uninterruptible for possible flush
- * wait, as in modesetting process we're not supposed to be interrupted.
+ * Prepare buffer for display plane (scanout, cursors, etc).
+ * Can be called from an uninterruptible phase (modesetting) and allows
+ * any flushes to be pipelined (for pageflips).
+ *
+ * For the display plane, we want to be in the GTT but out of any write
+ * domains. So in many ways this looks like set_to_gtt_domain() apart from the
+ * ability to pipeline the waits, pinning and any additional subtleties
+ * that may differentiate the display plane from ordinary buffers.
*/
int
-i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj,
+i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
+ u32 alignment,
struct intel_ring_buffer *pipelined)
{
- uint32_t old_read_domains;
+ u32 old_read_domains, old_write_domain;
int ret;
- /* Not valid to be called on unbound objects. */
- if (obj->gtt_space == NULL)
- return -EINVAL;
-
ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
-
- /* Currently, we are always called from an non-interruptible context. */
if (pipelined != obj->ring) {
ret = i915_gem_object_wait_rendering(obj);
- if (ret)
+ if (ret == -ERESTARTSYS)
return ret;
}
+ /* The display engine is not coherent with the LLC cache on gen6. As
+ * a result, we make sure that the pinning that is about to occur is
+ * done with uncached PTEs. This is lowest common denominator for all
+ * chipsets.
+ *
+ * However for gen6+, we could do better by using the GFDT bit instead
+ * of uncaching, which would allow us to flush all the LLC-cached data
+ * with that bit in the PTE to main memory with just one PIPE_CONTROL.
+ */
+ ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE);
+ if (ret)
+ return ret;
+
+ /* As the user may map the buffer once pinned in the display plane
+ * (e.g. libkms for the bootup splash), we have to ensure that we
+ * always use map_and_fenceable for all scanout buffers.
+ */
+ ret = i915_gem_object_pin(obj, alignment, true);
+ if (ret)
+ return ret;
+
i915_gem_object_flush_cpu_write_domain(obj);
+ old_write_domain = obj->base.write_domain;
old_read_domains = obj->base.read_domains;
+
+ /* It should now be out of any other write domains, and we can update
+ * the domain values for our changes.
+ */
+ BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
trace_i915_gem_object_change_domain(obj,
old_read_domains,
- obj->base.write_domain);
+ old_write_domain);
return 0;
}
int
-i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj)
+i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
{
int ret;
- if (!obj->active)
+ if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0)
return 0;
if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
@@ -3049,7 +3064,13 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj)
return ret;
}
- return i915_gem_object_wait_rendering(obj);
+ ret = i915_gem_object_wait_rendering(obj);
+ if (ret)
+ return ret;
+
+ /* Ensure that we invalidate the GPU's caches and TLBs. */
+ obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
+ return 0;
}
/**
@@ -3271,6 +3292,10 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
if (ret == 0 && atomic_read(&dev_priv->mm.wedged))
ret = -EIO;
+ } else if (wait_for_atomic(i915_seqno_passed(ring->get_seqno(ring),
+ seqno) ||
+ atomic_read(&dev_priv->mm.wedged), 3000)) {
+ ret = -EBUSY;
}
}
@@ -3474,9 +3499,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
* so emit a request to do so.
*/
request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request)
- ret = i915_add_request(obj->ring, NULL,request);
- else
+ if (request) {
+ ret = i915_add_request(obj->ring, NULL, request);
+ if (ret)
+ kfree(request);
+ } else
ret = -ENOMEM;
}
@@ -3500,7 +3527,7 @@ int
i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- return i915_gem_ring_throttle(dev, file_priv);
+ return i915_gem_ring_throttle(dev, file_priv);
}
int
@@ -3575,7 +3602,23 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
- obj->cache_level = I915_CACHE_NONE;
+ if (HAS_LLC(dev)) {
+ /* On some devices, we can have the GPU use the LLC (the CPU
+ * cache) for about a 10% performance improvement
+ * compared to uncached. Graphics requests other than
+ * display scanout are coherent with the CPU in
+ * accessing this cache. This means in this mode we
+ * don't need to clflush on the CPU side, and on the
+ * GPU side we only need to flush internal caches to
+ * get data visible to the CPU.
+ *
+ * However, we maintain the display planes as UC, and so
+ * need to rebind when first used as such.
+ */
+ obj->cache_level = I915_CACHE_LLC;
+ } else
+ obj->cache_level = I915_CACHE_NONE;
+
obj->base.driver_private = NULL;
obj->fence_reg = I915_FENCE_REG_NONE;
INIT_LIST_HEAD(&obj->mm_list);
@@ -3613,7 +3656,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj)
trace_i915_gem_object_destroy(obj);
if (obj->base.map_list.map)
- i915_gem_free_mmap_offset(obj);
+ drm_gem_free_mmap_offset(&obj->base);
drm_gem_object_release(&obj->base);
i915_gem_info_remove_obj(dev_priv, obj->base.size);
@@ -3650,7 +3693,7 @@ i915_gem_idle(struct drm_device *dev)
return 0;
}
- ret = i915_gpu_idle(dev);
+ ret = i915_gpu_idle(dev, true);
if (ret) {
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -3685,12 +3728,71 @@ i915_gem_idle(struct drm_device *dev)
return 0;
}
+void i915_gem_init_swizzling(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ if (INTEL_INFO(dev)->gen < 5 ||
+ dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
+ return;
+
+ I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
+ DISP_TILE_SURFACE_SWIZZLING);
+
+ if (IS_GEN5(dev))
+ return;
+
+ I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL);
+ if (IS_GEN6(dev))
+ I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB));
+ else
+ I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB));
+}
+
+void i915_gem_init_ppgtt(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t pd_offset;
+ struct intel_ring_buffer *ring;
+ int i;
+
+ if (!dev_priv->mm.aliasing_ppgtt)
+ return;
+
+ pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset;
+ pd_offset /= 64; /* in cachelines, */
+ pd_offset <<= 16;
+
+ if (INTEL_INFO(dev)->gen == 6) {
+ uint32_t ecochk = I915_READ(GAM_ECOCHK);
+ I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT |
+ ECOCHK_PPGTT_CACHE64B);
+ I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE));
+ } else if (INTEL_INFO(dev)->gen >= 7) {
+ I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B);
+ /* GFX_MODE is per-ring on gen7+ */
+ }
+
+ for (i = 0; i < I915_NUM_RINGS; i++) {
+ ring = &dev_priv->ring[i];
+
+ if (INTEL_INFO(dev)->gen >= 7)
+ I915_WRITE(RING_MODE_GEN7(ring),
+ GFX_MODE_ENABLE(GFX_PPGTT_ENABLE));
+
+ I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
+ I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
+ }
+}
+
int
-i915_gem_init_ringbuffer(struct drm_device *dev)
+i915_gem_init_hw(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
+ i915_gem_init_swizzling(dev);
+
ret = intel_init_render_ring_buffer(dev);
if (ret)
return ret;
@@ -3709,6 +3811,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
dev_priv->next_seqno = 1;
+ i915_gem_init_ppgtt(dev);
+
return 0;
cleanup_bsd_ring:
@@ -3746,7 +3850,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;
- ret = i915_gem_init_ringbuffer(dev);
+ ret = i915_gem_init_hw(dev);
if (ret != 0) {
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -3823,7 +3927,7 @@ i915_gem_load(struct drm_device *dev)
INIT_LIST_HEAD(&dev_priv->mm.gtt_list);
for (i = 0; i < I915_NUM_RINGS; i++)
init_ring_lists(&dev_priv->ring[i]);
- for (i = 0; i < 16; i++)
+ for (i = 0; i < I915_MAX_NUM_FENCES; i++)
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
i915_gem_retire_work_handler);
@@ -4141,7 +4245,7 @@ rescan:
* This has a dramatic impact to reduce the number of
* OOM-killer events whilst running the GPU aggressively.
*/
- if (i915_gpu_idle(dev) == 0)
+ if (i915_gpu_idle(dev, true) == 0)
goto rescan;
}
mutex_unlock(&dev->struct_mutex);
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_gem_debug.c smdk4210/drivers/gpu/drm/i915/i915_gem_debug.c
index 8da1899..cc93cac 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_gem_debug.c
+++ smdk4210/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -72,7 +72,7 @@ i915_verify_lists(struct drm_device *dev)
break;
} else if (!obj->active ||
(obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0 ||
- list_empty(&obj->gpu_write_list)){
+ list_empty(&obj->gpu_write_list)) {
DRM_ERROR("invalid flushing %p (a %d w %x gwl %d)\n",
obj,
obj->active,
@@ -157,7 +157,7 @@ i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle)
for (page = 0; page < obj->size / PAGE_SIZE; page++) {
int i;
- backing_map = kmap_atomic(obj->pages[page], KM_USER0);
+ backing_map = kmap_atomic(obj->pages[page]);
if (backing_map == NULL) {
DRM_ERROR("failed to map backing page\n");
@@ -181,13 +181,13 @@ i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle)
}
}
}
- kunmap_atomic(backing_map, KM_USER0);
+ kunmap_atomic(backing_map);
backing_map = NULL;
}
out:
if (backing_map != NULL)
- kunmap_atomic(backing_map, KM_USER0);
+ kunmap_atomic(backing_map);
iounmap(gtt_mapping);
/* give syslog time to catch up */
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_gem_evict.c smdk4210/drivers/gpu/drm/i915/i915_gem_evict.c
index da05a26..21a8271 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_gem_evict.c
+++ smdk4210/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -36,7 +36,6 @@ static bool
mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
{
list_add(&obj->exec_list, unwind);
- drm_gem_object_reference(&obj->base);
return drm_mm_scan_add_block(obj->gtt_space);
}
@@ -49,21 +48,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
struct drm_i915_gem_object *obj;
int ret = 0;
- i915_gem_retire_requests(dev);
-
- /* Re-check for free space after retiring requests */
- if (mappable) {
- if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
- min_size, alignment, 0,
- dev_priv->mm.gtt_mappable_end,
- 0))
- return 0;
- } else {
- if (drm_mm_search_free(&dev_priv->mm.gtt_space,
- min_size, alignment, 0))
- return 0;
- }
-
trace_i915_gem_evict(dev, min_size, alignment, mappable);
/*
@@ -122,7 +106,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
goto found;
}
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
- if (! obj->base.write_domain || obj->pin_count)
+ if (!obj->base.write_domain || obj->pin_count)
continue;
if (mark_free(obj, &unwind_list))
@@ -139,7 +123,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
BUG_ON(ret);
list_del_init(&obj->exec_list);
- drm_gem_object_unreference(&obj->base);
}
/* We expect the caller to unpin, evict all and try again, or give up.
@@ -158,10 +141,10 @@ found:
exec_list);
if (drm_mm_scan_remove_block(obj->gtt_space)) {
list_move(&obj->exec_list, &eviction_list);
+ drm_gem_object_reference(&obj->base);
continue;
}
list_del_init(&obj->exec_list);
- drm_gem_object_unreference(&obj->base);
}
/* Unbinding will emit any required flushes */
@@ -195,7 +178,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
trace_i915_gem_evict_everything(dev, purgeable_only);
/* Flush everything (on to the inactive lists) and evict */
- ret = i915_gpu_idle(dev);
+ ret = i915_gpu_idle(dev, true);
if (ret)
return ret;
diff --git aosp-v3.0/drivers/gpu/drm/i915/i915_gem_execbuffer.c smdk4210/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index bc927ae..028d1fa 100644
--- aosp-v3.0/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ smdk4210/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -32,6 +32,7 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
+#include <linux/dma_remapping.h>
struct change_domains {
uint32_t invalidate_domains;
@@ -202,9 +203,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
cd->invalidate_domains |= invalidate_domains;
cd->flush_domains |= flush_domains;
if (flush_domains & I915_GEM_GPU_DOMAINS)
- cd->flush_rings |= obj->ring->id;
+ cd->flush_rings |= intel_ring_flag(obj->ring);
if (invalidate_domains & I915_GEM_GPU_DOMAINS)
- cd->flush_rings |= ring->id;
+ cd->flush_rings |= intel_ring_flag(ring);
}
struct eb_objects {
@@ -286,14 +287,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
* exec_object list, so it should have a GTT space bound by now.
*/
if (unlikely(target_offset == 0)) {
- DRM_ERROR("No GTT space found for object %d\n",
+ DRM_DEBUG("No GTT space found for object %d\n",
reloc->target_handle);
return ret;
}
/* Validate that the target is in a valid r/w GPU domain */
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
- DRM_ERROR("reloc with multiple write domains: "
+ DRM_DEBUG("reloc with multiple write domains: "
"obj %p target %d offset %d "
"read %08x write %08x",
obj, reloc->target_handle,
@@ -302,8 +303,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
reloc->write_domain);
return ret;
}
- if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) {
- DRM_ERROR("reloc with read/write CPU domains: "
+ if (unlikely((reloc->write_domain | reloc->read_domains)
+ & ~I915_GEM_GPU_DOMAINS)) {
+ DRM_DEBUG("reloc with read/write non-GPU domains: "
"obj %p target %d offset %d "
"read %08x write %08x",
obj, reloc->target_handle,
@@ -314,7 +316,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
}
if (unlikely(reloc->write_domain && target_obj->pending_write_domain &&
reloc->write_domain != target_obj->pending_write_domain)) {
- DRM_ERROR("Write domain conflict: "
+ DRM_DEBUG("Write domain conflict: "
"obj %p target %d offset %d "
"new %08x old %08x\n",
obj, reloc->target_handle,
@@ -335,7 +337,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i91
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment